├── .gitignore
├── .travis.yml
├── LICENSE.txt
├── README.md
├── datatypes
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── modelmapper
│ │ └── module
│ │ └── jdk8
│ │ ├── FromOptionalConverter.java
│ │ ├── FromOptionalToOptionalConverter.java
│ │ ├── Jdk8Module.java
│ │ └── ToOptionalConverter.java
│ └── test
│ └── java
│ └── org
│ └── modelmapper
│ └── module
│ └── jdk8
│ ├── FromOptionalConverterTest.java
│ ├── FromOptionalToOptionalConverterTest.java
│ └── ToOptionalConverterTest.java
├── datetime
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── modelmapper
│ │ └── module
│ │ └── jsr310
│ │ ├── FromTemporalConverter.java
│ │ ├── Jsr310Module.java
│ │ ├── Jsr310ModuleConfig.java
│ │ ├── TemporalToTemporalConverter.java
│ │ └── ToTemporalConverter.java
│ └── test
│ └── java
│ └── org
│ └── modelmapper
│ └── module
│ └── jsr310
│ ├── FromInstantConverterTest.java
│ ├── FromLocalDateConverterTest.java
│ ├── FromLocalDateTimeConverterTest.java
│ ├── FromOffsetDateTimeConverterTest.java
│ ├── FromZonedDateTimeConverterTest.java
│ ├── Jsr310ModuleTest.java
│ ├── TestHelper.java
│ ├── ToInstantConverterTest.java
│ ├── ToLocalDateConverterTest.java
│ ├── ToLocalDateTimeConverterTest.java
│ ├── ToOffsetDateTimeConverterTest.java
│ └── ToZonedDateTimeConverterTest.java
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | target/
3 | docs/
4 | test-output/
5 | release.properties
6 | .project
7 | .classpath
8 | .settings/
9 | _site/
10 | user-manual/
11 | .idea
12 | *.iml
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | sudo: required
3 | dist: trusty
4 |
5 | jdk:
6 | - oraclejdk8
7 | - oraclejdk9
8 |
9 | notifications:
10 | email: false
11 |
12 | # whitelist
13 | branches:
14 | only:
15 | - master
16 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ModelMapper Module for Java8
2 |
3 | [](https://travis-ci.org/modelmapper/modelmapper-module-java8)
4 | [](http://www.apache.org/licenses/LICENSE-2.0.html)
5 | [](https://maven-badges.herokuapp.com/maven-central/com.github.chhsiao90/modelmapper-module-java8)
6 |
7 | This is a module for [ModelMapper](http://modelmapper.org) to support Java 8 features.
8 |
9 | ## Java 8 Date/Time
10 |
11 | ### Registers the module
12 |
13 | ```java
14 | modelMapper.registerModule(new Jsr310Module());
15 | ```
16 |
17 | ### Configuration
18 |
19 | We also support for configuration.
20 |
21 | ```java
22 | // using String patterns
23 | Jsr310ModuleConfig config = Jsr310ModuleConfig.builder()
24 | .dateTimePattern("yyyy-MM-dd HH:mm:ss") // default is yyyy-MM-dd HH:mm:ss
25 | .datePattern("yyyy-MM-dd") // default is yyyy-MM-dd
26 | .zoneId(ZoneOffset.UTC) // default is ZoneId.systemDefault()
27 | .build()
28 | modelMapper.registerModule(new Jsr310Module(config));
29 | ```
30 | ```java
31 | // using DateTimeFormatter directly
32 | Jsr310ModuleConfig config = Jsr310ModuleConfig.builder()
33 | .dateTimeFormatter(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
34 | .dateFormatter(DateTimeFormatter.ISO_LOCAL_DATE)
35 | .zoneId(ZoneOffset.UTC)
36 | .build()
37 | modelMapper.registerModule(new Jsr310Module(config));
38 | ```
39 |
40 | ### Support Mappings
41 |
42 | | Source Type | Destination Type |
43 | |---------------|------------------|
44 | | LocalDateTime | String |
45 | | LocalDateTime | Long/long |
46 | | LocalDateTime | BigDecimal |
47 | | LocalDateTime | BigInteger |
48 | | LocalDateTime | Date |
49 | | LocalDateTime | Calendar |
50 | | LocalDate | String |
51 | | LocalDate | Long/long |
52 | | LocalDate | BigDecimal |
53 | | LocalDate | BigInteger |
54 | | LocalDate | Date |
55 | | LocalDate | Calendar |
56 | | OffsetDateTime| String |
57 | | OffsetDateTime| Long/long |
58 | | OffsetDateTime| BigDecimal |
59 | | OffsetDateTime| BigInteger |
60 | | OffsetDateTime| Date |
61 | | OffsetDateTime| Calendar |
62 | | Instant | String |
63 | | Instant | Long/long |
64 | | Instant | BigDecimal |
65 | | Instant | BigInteger |
66 | | Instant | Date |
67 | | Instant | Calendar |
68 | | String | LocalDateTime |
69 | | Long/long | LocalDateTime |
70 | | BigDecimal | LocalDateTime |
71 | | BigInteger | LocalDateTime |
72 | | Date | LocalDateTime |
73 | | Calendar | LocalDateTime |
74 | | String | DateTime |
75 | | Long/long | DateTime |
76 | | BigDecimal | DateTime |
77 | | BigInteger | DateTime |
78 | | Date | DateTime |
79 | | Calendar | DateTime |
80 | | String | OffsetDateTime |
81 | | Long/long | OffsetDateTime |
82 | | BigDecimal | OffsetDateTime |
83 | | BigInteger | OffsetDateTime |
84 | | Date | OffsetDateTime |
85 | | Calendar | OffsetDateTime |
86 | | String | Instant |
87 | | Long/long | Instant |
88 | | BigDecimal | Instant |
89 | | BigInteger | Instant |
90 | | Date | Instant |
91 | | Calendar | Instant |
92 |
--------------------------------------------------------------------------------
/datatypes/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.modelmapper
5 | modelmapper-module-java8
6 | 1.2.4-SNAPSHOT
7 |
8 | 4.0.0
9 | modelmapper-module-java8-datatypes
10 | ModelMapper Module Java8 Data Types
11 | ModelMapper Module for Java8 Data Types
12 |
13 |
14 | org.modelmapper
15 | modelmapper
16 |
17 |
18 | org.projectlombok
19 | lombok
20 | true
21 |
22 |
23 |
--------------------------------------------------------------------------------
/datatypes/src/main/java/org/modelmapper/module/jdk8/FromOptionalConverter.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jdk8;
2 |
3 | import java.util.Optional;
4 | import org.modelmapper.spi.ConditionalConverter;
5 | import org.modelmapper.spi.MappingContext;
6 |
7 | /**
8 | * Converts {@link Optional} to {@link Object}
9 | *
10 | * @author Chun Han Hsiao
11 | */
12 | public class FromOptionalConverter implements ConditionalConverter, Object> {
13 | @Override
14 | public MatchResult match(Class> sourceType, Class> destinationType) {
15 | return (Optional.class.equals(sourceType) && !Optional.class.equals(destinationType))
16 | ? MatchResult.FULL
17 | : MatchResult.NONE;
18 | }
19 |
20 | @Override
21 | public Object convert(MappingContext, Object> mappingContext) {
22 | if (mappingContext.getSource() == null || !mappingContext.getSource().isPresent()) {
23 | return null;
24 | }
25 |
26 | MappingContext propertyContext = mappingContext.create(
27 | mappingContext.getSource().get(), mappingContext.getDestinationType());
28 | return mappingContext.getMappingEngine().map(propertyContext);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/datatypes/src/main/java/org/modelmapper/module/jdk8/FromOptionalToOptionalConverter.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jdk8;
2 |
3 | import org.modelmapper.internal.typetools.TypeResolver;
4 | import org.modelmapper.internal.util.Types;
5 | import org.modelmapper.spi.ConditionalConverter;
6 | import org.modelmapper.spi.Mapping;
7 | import org.modelmapper.spi.MappingContext;
8 | import org.modelmapper.spi.PropertyInfo;
9 | import org.modelmapper.spi.PropertyMapping;
10 |
11 | import java.lang.reflect.ParameterizedType;
12 | import java.util.Optional;
13 |
14 | /**
15 | * Converts {@link Optional} to {@link Optional}
16 | */
17 | public class FromOptionalToOptionalConverter implements ConditionalConverter, Optional>> {
18 | @Override
19 | public MatchResult match(Class> sourceType, Class> destinationType) {
20 | return (Optional.class.equals(sourceType) && Optional.class.equals(destinationType))
21 | ? MatchResult.FULL
22 | : MatchResult.NONE;
23 | }
24 |
25 | @Override
26 | @SuppressWarnings("all")
27 | public Optional> convert(MappingContext, Optional>> mappingContext) {
28 | Class> optionalType = getElementType(mappingContext);
29 | Optional> source = mappingContext.getSource();
30 | if (source == null) {
31 | return null;
32 | } else if (source.isPresent()) {
33 | MappingContext, ?> optionalContext = mappingContext.create(source.get(), optionalType);
34 | return Optional.ofNullable(mappingContext.getMappingEngine().map(optionalContext));
35 | } else {
36 | return Optional.empty();
37 | }
38 | }
39 |
40 |
41 | private Class> getElementType(MappingContext, Optional>> mappingContext) {
42 | Mapping mapping = mappingContext.getMapping();
43 | if (mapping instanceof PropertyMapping) {
44 | PropertyInfo destInfo = mapping.getLastDestinationProperty();
45 | Class> elementType = TypeResolver.resolveRawArgument(destInfo.getGenericType(),
46 | destInfo.getInitialType());
47 | return elementType == TypeResolver.Unknown.class ? Object.class : elementType;
48 | } else if (mappingContext.getGenericDestinationType() instanceof ParameterizedType) {
49 | return Types.rawTypeFor(((ParameterizedType) mappingContext.getGenericDestinationType()).getActualTypeArguments()[0]);
50 | }
51 |
52 | return Object.class;
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/datatypes/src/main/java/org/modelmapper/module/jdk8/Jdk8Module.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jdk8;
2 |
3 | import org.modelmapper.ModelMapper;
4 | import org.modelmapper.Module;
5 |
6 | /**
7 | * Supports the JDK8 data types with ModelMapper
8 | *
9 | * @author Chun Han Hsiao
10 | */
11 | public class Jdk8Module implements Module {
12 | @Override
13 | public void setupModule(ModelMapper modelMapper) {
14 | modelMapper.getConfiguration().getConverters().add(0, new FromOptionalConverter());
15 | modelMapper.getConfiguration().getConverters().add(0, new ToOptionalConverter());
16 | modelMapper.getConfiguration().getConverters().add(0, new FromOptionalToOptionalConverter());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/datatypes/src/main/java/org/modelmapper/module/jdk8/ToOptionalConverter.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jdk8;
2 |
3 | import java.util.Optional;
4 | import org.modelmapper.internal.util.MappingContextHelper;
5 | import org.modelmapper.spi.ConditionalConverter;
6 | import org.modelmapper.spi.MappingContext;
7 |
8 | /**
9 | * Converts {@link Object} to {@link Optional}
10 | *
11 | * @author Chun Han Hsiao
12 | */
13 | public class ToOptionalConverter implements ConditionalConverter> {
14 | @Override
15 | public MatchResult match(Class> sourceType, Class> destinationType) {
16 | return (!Optional.class.equals(sourceType) && Optional.class.equals(destinationType))
17 | ? MatchResult.FULL
18 | : MatchResult.NONE;
19 | }
20 |
21 | @Override
22 | public Optional convert(MappingContext> mappingContext) {
23 | if (mappingContext.getSource() == null) {
24 | return Optional.empty();
25 | }
26 |
27 | MappingContext, ?> propertyContext = mappingContext.create(
28 | mappingContext.getSource(), MappingContextHelper.resolveDestinationGenericType(mappingContext));
29 | Object destination = mappingContext.getMappingEngine().map(propertyContext);
30 | return Optional.ofNullable(destination);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/datatypes/src/test/java/org/modelmapper/module/jdk8/FromOptionalConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jdk8;
2 |
3 | import static org.testng.Assert.assertEquals;
4 | import static org.testng.Assert.assertNull;
5 |
6 | import java.util.Optional;
7 | import lombok.AllArgsConstructor;
8 | import lombok.Data;
9 | import org.modelmapper.Converter;
10 | import org.modelmapper.ModelMapper;
11 | import org.testng.annotations.BeforeMethod;
12 | import org.testng.annotations.Test;
13 |
14 | @Test
15 | public class FromOptionalConverterTest {
16 | private ModelMapper modelMapper;
17 |
18 | @Data
19 | @AllArgsConstructor
20 | static class Field {
21 | private String value;
22 | }
23 |
24 | @Data
25 | static class FieldDto {
26 | private String value;
27 | }
28 |
29 | @Data
30 | @AllArgsConstructor
31 | @SuppressWarnings("all")
32 | static class Source {
33 | Optional field;
34 | }
35 |
36 | @Data
37 | static class Destination {
38 | FieldDto field;
39 | }
40 |
41 | @BeforeMethod
42 | public void setUp() {
43 | modelMapper = new ModelMapper();
44 | modelMapper.registerModule(new Jdk8Module());
45 |
46 | Converter upperCase = ctx -> ctx.getSource().toUpperCase();
47 | modelMapper.emptyTypeMap(Field.class, FieldDto.class).addMappings(
48 | mapper -> mapper.using(upperCase).map(Field::getValue, FieldDto::setValue));
49 | }
50 |
51 |
52 | public void shouldMapOptionalStringToString() {
53 | assertEquals(modelMapper.map(Optional.of("foo"), String.class), "foo");
54 | assertNull(modelMapper.map(Optional.empty(), String.class));
55 | }
56 |
57 | public void shouldMapOptionalStringToInteger() {
58 | assertEquals((int) modelMapper.map(Optional.of("100"), Integer.class), 100);
59 | }
60 |
61 | public void shouldMapOptionalProperty() {
62 | Destination destination = modelMapper.map(new Source(Optional.of(new Field("foo"))), Destination.class);
63 | assertEquals(destination.getField().getValue(), "FOO");
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/datatypes/src/test/java/org/modelmapper/module/jdk8/FromOptionalToOptionalConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jdk8;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import org.modelmapper.Converter;
6 | import org.modelmapper.ModelMapper;
7 | import org.modelmapper.TypeToken;
8 | import org.testng.annotations.BeforeMethod;
9 | import org.testng.annotations.Test;
10 |
11 | import java.lang.reflect.Type;
12 | import java.util.Optional;
13 |
14 | import static org.testng.Assert.assertEquals;
15 | import static org.testng.Assert.assertNull;
16 |
17 | @Test
18 | public class FromOptionalToOptionalConverterTest {
19 | private ModelMapper modelMapper;
20 |
21 | @Data
22 | @AllArgsConstructor
23 | static class Field {
24 | private String value;
25 | }
26 |
27 | @Data
28 | static class FieldDto {
29 | private String value;
30 | }
31 |
32 | @Data
33 | @AllArgsConstructor
34 | @SuppressWarnings("all")
35 | static class Source {
36 | private Optional field;
37 | }
38 |
39 | @Data
40 | @SuppressWarnings("all")
41 | static class Destination {
42 | private Optional field;
43 | }
44 |
45 | @BeforeMethod
46 | public void setUp() {
47 | modelMapper = new ModelMapper();
48 | modelMapper.registerModule(new Jdk8Module());
49 |
50 | Converter upperCase = ctx -> ctx.getSource().toUpperCase();
51 | modelMapper.emptyTypeMap(Field.class, FieldDto.class).addMappings(
52 | mapper -> mapper.using(upperCase).map(Field::getValue, FieldDto::setValue));
53 | }
54 |
55 |
56 | public void shouldMapOptionalStringToOptionalString() {
57 | assertEquals(modelMapper.map(Optional.of("foo"), Optional.class), Optional.of("foo"));
58 | assertEquals(modelMapper.map(Optional.empty(), Optional.class), Optional.empty());
59 | }
60 |
61 | public void shouldMapOptionalStringToOptionalInteger() {
62 | Type type = new TypeToken>() {}.getType();
63 | assertEquals(modelMapper.map(Optional.of("100"), type), Optional.of(100));
64 | }
65 |
66 | @SuppressWarnings("all")
67 | public void shouldMapOptionalPropertyToOtherOptionalProperty() {
68 | Destination destination = modelMapper.map(new Source(Optional.of(new Field("foo"))), Destination.class);
69 | assertEquals(destination.getField().get().getValue(), "FOO");
70 | }
71 |
72 | public void shouldMapNullToNull() {
73 | Destination destination = modelMapper.map(new Source(null), Destination.class);
74 | assertNull(destination.getField());
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/datatypes/src/test/java/org/modelmapper/module/jdk8/ToOptionalConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jdk8;
2 |
3 | import static org.testng.Assert.assertEquals;
4 | import static org.testng.Assert.assertFalse;
5 | import static org.testng.Assert.assertNull;
6 | import static org.testng.Assert.assertTrue;
7 |
8 | import java.util.Optional;
9 | import lombok.AllArgsConstructor;
10 | import lombok.Data;
11 | import org.modelmapper.Converter;
12 | import org.modelmapper.ModelMapper;
13 | import org.modelmapper.TypeToken;
14 | import org.testng.annotations.BeforeMethod;
15 | import org.testng.annotations.Test;
16 |
17 | @Test
18 | public class ToOptionalConverterTest {
19 | private ModelMapper modelMapper;
20 |
21 | @Data
22 | @AllArgsConstructor
23 | static class Field {
24 | private String value;
25 | }
26 |
27 | @Data
28 | static class FieldDto {
29 | private String value;
30 | }
31 |
32 | @Data
33 | @AllArgsConstructor
34 | static class Source {
35 | Field field;
36 | }
37 |
38 | @Data
39 | @SuppressWarnings("all")
40 | static class Destination {
41 | Optional field;
42 | }
43 |
44 | @BeforeMethod
45 | public void setUp() {
46 | modelMapper = new ModelMapper();
47 | modelMapper.registerModule(new Jdk8Module());
48 |
49 | Converter upperCase = ctx -> ctx.getSource().toUpperCase();
50 | modelMapper.emptyTypeMap(Field.class, FieldDto.class).addMappings(
51 | mapper -> mapper.using(upperCase).map(Field::getValue, FieldDto::setValue));
52 | }
53 |
54 |
55 | @SuppressWarnings("all")
56 | public void shouldMapStringToOptional() {
57 | assertEquals(modelMapper.map("foo", Optional.class).get(), "foo");
58 | }
59 |
60 | public void shouldMapStringToOptionalInteger() {
61 | assertEquals(modelMapper.map("100", new TypeToken>() {}.getType()), Optional.of(100));
62 | }
63 |
64 | @SuppressWarnings("all")
65 | public void shouldMapToOptionalProperty() {
66 | Destination destination = modelMapper.map(new Source(new Field("foo")), Destination.class);
67 | assertEquals(destination.getField().get().getValue(), "FOO");
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/datetime/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.modelmapper
5 | modelmapper-module-java8
6 | 1.2.4-SNAPSHOT
7 |
8 | jar
9 | 4.0.0
10 | modelmapper-module-jsr310
11 | ModelMapper Module JSR310
12 | ModelMapper Module for JSR310
13 |
14 |
15 | org.modelmapper
16 | modelmapper
17 |
18 |
19 | org.projectlombok
20 | lombok
21 | true
22 |
23 |
24 |
--------------------------------------------------------------------------------
/datetime/src/main/java/org/modelmapper/module/jsr310/FromTemporalConverter.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import java.math.BigDecimal;
4 | import java.math.BigInteger;
5 | import java.time.*;
6 | import java.time.temporal.Temporal;
7 | import java.util.Calendar;
8 | import java.util.Date;
9 | import org.modelmapper.Converter;
10 | import org.modelmapper.internal.Errors;
11 | import org.modelmapper.spi.ConditionalConverter;
12 | import org.modelmapper.spi.MappingContext;
13 |
14 | /**
15 | * Converts {@link Temporal} to {@link Object}
16 | *
17 | * @author Chun Han Hsiao
18 | */
19 | public class FromTemporalConverter implements ConditionalConverter {
20 | private Jsr310ModuleConfig config;
21 | private final LocalDateTimeConverter localDateTimeConverter = new LocalDateTimeConverter();
22 | private final ZonedDateTimeConverter zonedDateTimeConverter = new ZonedDateTimeConverter();
23 | private final LocalDateConverter localDateConverter = new LocalDateConverter();
24 | private final OffsetDateTimeConverter offsetDateTimeConverter = new OffsetDateTimeConverter();
25 | private final InstantConverter instantConverter = new InstantConverter();
26 |
27 | public FromTemporalConverter(Jsr310ModuleConfig config) {
28 | this.config = config;
29 | }
30 |
31 | @Override
32 | public MatchResult match(Class> sourceType, Class> destinationType) {
33 | return Temporal.class.isAssignableFrom(sourceType)
34 | ? MatchResult.FULL : MatchResult.NONE;
35 | }
36 |
37 | @Override
38 | public Object convert(MappingContext mappingContext) {
39 | if (mappingContext.getSource() == null)
40 | return null;
41 |
42 | Class> sourceType = mappingContext.getSourceType();
43 | if (LocalDateTime.class.equals(sourceType))
44 | return localDateTimeConverter.convert(mappingContext);
45 | else if (LocalDate.class.equals(sourceType))
46 | return localDateConverter.convert(mappingContext);
47 | else if (OffsetDateTime.class.equals(sourceType))
48 | return offsetDateTimeConverter.convert(mappingContext);
49 | else if (Instant.class.equals(sourceType))
50 | return instantConverter.convert(mappingContext);
51 | else if (ZonedDateTime.class.equals(sourceType))
52 | return zonedDateTimeConverter.convert(mappingContext);
53 | else
54 | throw new Errors().addMessage("Unsupported mapping types[%s->%s]",
55 | LocalDateTime.class.getName(), mappingContext.getDestinationType().getName())
56 | .toMappingException();
57 | }
58 |
59 | private class LocalDateTimeConverter implements Converter {
60 | @Override
61 | public Object convert(MappingContext mappingContext) {
62 | LocalDateTime source = (LocalDateTime) mappingContext.getSource();
63 | return convertLocalDateTime(source, mappingContext);
64 | }
65 | }
66 |
67 | private class ZonedDateTimeConverter implements Converter {
68 | @Override
69 | public Object convert(MappingContext mappingContext) {
70 | ZonedDateTime source = (ZonedDateTime) mappingContext.getSource();
71 | return convertZonedDateTime(source, mappingContext);
72 | }
73 | }
74 |
75 | private class LocalDateConverter implements Converter {
76 | @Override
77 | public Object convert(MappingContext mappingContext) {
78 | LocalDate source = (LocalDate) mappingContext.getSource();
79 | Class> destinationType = mappingContext.getDestinationType();
80 | if (destinationType.equals(String.class))
81 | return config.getDateFormatter()
82 | .format(source);
83 |
84 | LocalDateTime localDateTime = source.atStartOfDay();
85 | return convertLocalDateTime(localDateTime, mappingContext);
86 | }
87 | }
88 |
89 | private class OffsetDateTimeConverter implements Converter {
90 | @Override
91 | public Object convert(MappingContext mappingContext) {
92 | OffsetDateTime source = (OffsetDateTime) mappingContext.getSource();
93 | return convertOffsetDateTime(source, mappingContext);
94 | }
95 | }
96 |
97 | private class InstantConverter implements Converter {
98 | @Override
99 | public Object convert(MappingContext mappingContext) {
100 | Instant source = (Instant) mappingContext.getSource();
101 | return convertInstant(source, mappingContext);
102 | }
103 | }
104 |
105 | private Object convertLocalDateTime(LocalDateTime source, MappingContext, ?> mappingContext) {
106 | Class> destinationType = mappingContext.getDestinationType();
107 | if (destinationType.equals(String.class))
108 | return config.getDateTimeFormatter()
109 | .format(source);
110 |
111 | Instant instant = source.atZone(config.getZoneId()).toInstant();
112 | return convertInstant(instant, mappingContext);
113 | }
114 |
115 | private Object convertZonedDateTime(ZonedDateTime source, MappingContext, ?> mappingContext) {
116 | Class> destinationType = mappingContext.getDestinationType();
117 | if (destinationType.equals(String.class))
118 | return config.getDateTimeOffsetFormatter()
119 | .format(source);
120 |
121 | Instant instant = source.toInstant();
122 | return convertInstant(instant, mappingContext);
123 | }
124 |
125 |
126 | private Object convertOffsetDateTime(OffsetDateTime source, MappingContext, ?> mappingContext) {
127 | Class> destinationType = mappingContext.getDestinationType();
128 | if (destinationType.equals(String.class))
129 | return config.getDateTimeOffsetFormatter()
130 | .format(source);
131 |
132 | Instant instant = source.toInstant();
133 | return convertInstant(instant, mappingContext);
134 | }
135 |
136 | private Object convertInstant(Instant source, MappingContext, ?> mappingContext) {
137 | Class> destinationType = mappingContext.getDestinationType();
138 | if (destinationType.equals(String.class))
139 | return config.getDateTimeFormatter()
140 | .withZone(config.getZoneId())
141 | .format(source);
142 | else if (Date.class.isAssignableFrom(destinationType))
143 | return new Date(epochMilliOf(source));
144 | else if (Calendar.class.isAssignableFrom(destinationType))
145 | return calendarOf(source);
146 | else if (Long.class.equals(destinationType) || Long.TYPE.equals(destinationType))
147 | return epochMilliOf(source);
148 | else if (BigDecimal.class.equals(destinationType))
149 | return new BigDecimal(epochMilliOf(source));
150 | else if (BigInteger.class.equals(destinationType))
151 | return BigInteger.valueOf(epochMilliOf(source));
152 | else
153 | throw new Errors().addMessage("Unsupported mapping types[%s->%s]",
154 | mappingContext.getSourceType().getName(), destinationType.getName())
155 | .toMappingException();
156 | }
157 |
158 | private long epochMilliOf(Instant instant) {
159 | return instant.toEpochMilli();
160 | }
161 |
162 | private Calendar calendarOf(Instant instant) {
163 | Calendar calendar = Calendar.getInstance();
164 | calendar.setTimeInMillis(epochMilliOf(instant));
165 | return calendar;
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/datetime/src/main/java/org/modelmapper/module/jsr310/Jsr310Module.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import org.modelmapper.ModelMapper;
4 | import org.modelmapper.Module;
5 |
6 | /**
7 | * Supports the JSR310 {@code java.time} objects with ModelMapper
8 | *
9 | * @author Chun Han Hsiao
10 | */
11 | public class Jsr310Module implements Module {
12 | private Jsr310ModuleConfig config;
13 |
14 | public Jsr310Module() {
15 | this(Jsr310ModuleConfig.builder().build());
16 | }
17 |
18 | public Jsr310Module(Jsr310ModuleConfig config) {
19 | this.config = config;
20 | }
21 |
22 | @Override
23 | public void setupModule(ModelMapper modelMapper) {
24 | modelMapper.getConfiguration().getConverters().add(0, new FromTemporalConverter(config));
25 | modelMapper.getConfiguration().getConverters().add(0, new ToTemporalConverter(config));
26 | modelMapper.getConfiguration().getConverters().add(0, new TemporalToTemporalConverter());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/datetime/src/main/java/org/modelmapper/module/jsr310/Jsr310ModuleConfig.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import java.time.ZoneId;
4 | import java.time.format.DateTimeFormatter;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * Config for {@link Jsr310Module}
11 | *
12 | * @author Chun Han Hsiao
13 | */
14 | @Data
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 | public class Jsr310ModuleConfig {
18 | private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
19 | private static final String DEFAULT_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
20 | private static final String DEFAULT_DATE_TIME_OFFSET_PATTERN = "yyyy-MM-dd HH:mm:ssX";
21 | private static final String DEFAULT_TIME_PATTERN = "HH:mm:ss";
22 |
23 | private DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN);
24 | private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN);
25 | private DateTimeFormatter dateTimeOffsetFormatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_OFFSET_PATTERN);
26 | private DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN);
27 | private ZoneId zoneId = ZoneId.systemDefault();
28 |
29 | public void setDatePattern(String datePattern) {
30 | this.setDateFormatter(DateTimeFormatter.ofPattern(datePattern));
31 | }
32 |
33 | public void setDateTimePattern(String dateTimePattern) {
34 | this.setDateTimeFormatter(DateTimeFormatter.ofPattern(dateTimePattern));
35 | }
36 |
37 | public void setDateTimeOffsetPattern(String dateTimeOffsetPattern) {
38 | this.setDateTimeOffsetFormatter(DateTimeFormatter.ofPattern(dateTimeOffsetPattern));
39 | }
40 |
41 | public void setTimePattern(String timePattern) {
42 | this.setTimeFormatter(DateTimeFormatter.ofPattern(timePattern));
43 | }
44 |
45 | public static Jsr310ModuleConfigBuilder builder() {
46 | return new Jsr310ModuleConfigBuilder();
47 | }
48 |
49 | public static class Jsr310ModuleConfigBuilder {
50 |
51 | private DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN);
52 | private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN);
53 | private DateTimeFormatter dateTimeOffsetFormatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_OFFSET_PATTERN);
54 | private DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN);
55 | private ZoneId zoneId = ZoneId.systemDefault();
56 |
57 | public Jsr310ModuleConfigBuilder datePattern(String datePattern) {
58 | return this.dateFormatter(DateTimeFormatter.ofPattern(datePattern));
59 | }
60 |
61 | public Jsr310ModuleConfigBuilder dateFormatter(DateTimeFormatter dateFormatter) {
62 | this.dateFormatter = dateFormatter;
63 | return this;
64 | }
65 |
66 | public Jsr310ModuleConfigBuilder dateTimePattern(String dateTimePattern) {
67 | return this.dateTimeFormatter(DateTimeFormatter.ofPattern(dateTimePattern));
68 | }
69 |
70 | public Jsr310ModuleConfigBuilder dateTimeFormatter(DateTimeFormatter dateTimeFormatter) {
71 | this.dateTimeFormatter = dateTimeFormatter;
72 | return this;
73 | }
74 |
75 | public Jsr310ModuleConfigBuilder dateTimeOffsetPattern(String dateTimeOffsetPattern) {
76 | return this.dateTimeOffsetFormatter(DateTimeFormatter.ofPattern(dateTimeOffsetPattern));
77 | }
78 |
79 | public Jsr310ModuleConfigBuilder dateTimeOffsetFormatter(DateTimeFormatter dateTimeOffsetFormatter) {
80 | this.dateTimeOffsetFormatter = dateTimeOffsetFormatter;
81 | return this;
82 | }
83 |
84 | public Jsr310ModuleConfigBuilder timePattern(String timePattern) {
85 | return this.timeFormatter(DateTimeFormatter.ofPattern(timePattern));
86 | }
87 |
88 | public Jsr310ModuleConfigBuilder timeFormatter(DateTimeFormatter timeFormatter) {
89 | this.timeFormatter = timeFormatter;
90 | return this;
91 | }
92 |
93 | public Jsr310ModuleConfigBuilder zoneId(ZoneId zoneId) {
94 | this.zoneId = zoneId;
95 | return this;
96 | }
97 |
98 | public Jsr310ModuleConfig build() {
99 | return new Jsr310ModuleConfig(dateFormatter, dateTimeFormatter, dateTimeOffsetFormatter, timeFormatter, zoneId);
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/datetime/src/main/java/org/modelmapper/module/jsr310/TemporalToTemporalConverter.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import java.time.temporal.Temporal;
4 | import org.modelmapper.internal.Errors;
5 | import org.modelmapper.spi.ConditionalConverter;
6 | import org.modelmapper.spi.MappingContext;
7 |
8 | /**
9 | * Converts {@link Temporal} to {@link Temporal}
10 | *
11 | * @author Chun Han Hsiao
12 | */
13 | public class TemporalToTemporalConverter implements ConditionalConverter {
14 | @Override
15 | public MatchResult match(Class> sourceType, Class> destinationType) {
16 | return Temporal.class.isAssignableFrom(sourceType)
17 | && Temporal.class.isAssignableFrom(destinationType)
18 | ? MatchResult.FULL : MatchResult.NONE;
19 | }
20 |
21 | @Override
22 | public Temporal convert(MappingContext mappingContext) {
23 | if (mappingContext.getSource() == null)
24 | return null;
25 | else if (mappingContext.getSourceType().equals(mappingContext.getDestinationType()))
26 | return mappingContext.getSource();
27 | else
28 | throw new Errors().addMessage("Unsupported mapping types[%s->%s]",
29 | mappingContext.getSourceType().getName(), mappingContext.getDestinationType())
30 | .toMappingException();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/datetime/src/main/java/org/modelmapper/module/jsr310/ToTemporalConverter.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import java.time.*;
4 | import java.time.temporal.Temporal;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 | import org.modelmapper.Converter;
8 | import org.modelmapper.internal.Errors;
9 | import org.modelmapper.spi.ConditionalConverter;
10 | import org.modelmapper.spi.MappingContext;
11 |
12 | /**
13 | * Converts {@link Object} to {@link Temporal}
14 | *
15 | * @author Chun Han Hsiao
16 | */
17 | public class ToTemporalConverter implements ConditionalConverter {
18 | private Jsr310ModuleConfig config;
19 | private final LocalDateTimeConverter localDateTimeConverter = new LocalDateTimeConverter();
20 | private final ZonedDateTimeConverter zonedDateTimeConverter = new ZonedDateTimeConverter();
21 | private final LocalDateConverter localDateConverter = new LocalDateConverter();
22 | private final OffsetDateTimeConverter offsetDateTimeConverter = new OffsetDateTimeConverter();
23 | private final InstantConverter instantConverter = new InstantConverter();
24 |
25 | public ToTemporalConverter(Jsr310ModuleConfig config) {
26 | this.config = config;
27 | }
28 |
29 | @Override
30 | public MatchResult match(Class> sourceType, Class> destinationType) {
31 | return Temporal.class.isAssignableFrom(destinationType)
32 | ? MatchResult.FULL : MatchResult.NONE;
33 | }
34 |
35 | @Override
36 | public Temporal convert(MappingContext mappingContext) {
37 | if (mappingContext.getSource() == null)
38 | return null;
39 |
40 | Class> destinationType = mappingContext.getDestinationType();
41 | if (LocalDateTime.class.equals(destinationType))
42 | return localDateTimeConverter.convert(mappingContext);
43 | else if (LocalDate.class.equals(destinationType))
44 | return localDateConverter.convert(mappingContext);
45 | else if (OffsetDateTime.class.equals(destinationType))
46 | return offsetDateTimeConverter.convert(mappingContext);
47 | else if (Instant.class.equals(destinationType))
48 | return instantConverter.convert(mappingContext);
49 | else if (ZonedDateTime.class.equals(destinationType))
50 | return zonedDateTimeConverter.convert(mappingContext);
51 | else
52 | throw new Errors().addMessage("Unsupported mapping types[%s->%s]",
53 | mappingContext.getSourceType().getName(), destinationType.getName())
54 | .toMappingException();
55 | }
56 |
57 | private class LocalDateTimeConverter implements Converter {
58 | @Override
59 | public Temporal convert(MappingContext mappingContext) {
60 | return convertLocalDateTime(mappingContext);
61 | }
62 | }
63 |
64 | private class ZonedDateTimeConverter implements Converter {
65 | @Override
66 | public Temporal convert(MappingContext mappingContext) {
67 | return convertZonedDateTime(mappingContext);
68 | }
69 | }
70 |
71 | private class LocalDateConverter implements Converter {
72 | @Override
73 | public Temporal convert(MappingContext mappingContext) {
74 | return convertLocalDate(mappingContext);
75 | }
76 | }
77 |
78 | private class OffsetDateTimeConverter implements Converter {
79 | @Override
80 | public Temporal convert(MappingContext mappingContext) {
81 | return convertOffsetDateTime(mappingContext);
82 | }
83 | }
84 |
85 | private class InstantConverter implements Converter {
86 | @Override
87 | public Temporal convert(MappingContext mappingContext) {
88 | return convertInstant(mappingContext);
89 | }
90 | }
91 |
92 | private LocalDate convertLocalDate(MappingContext, ?> mappingContext) {
93 | Object source = mappingContext.getSource();
94 | Class> sourceType = source.getClass();
95 | if (sourceType.equals(String.class))
96 | return LocalDate.parse((String) source,
97 | config.getDateFormatter());
98 | return convertInstant(mappingContext).atZone(config.getZoneId()).toLocalDate();
99 | }
100 |
101 | private LocalDateTime convertLocalDateTime(MappingContext, ?> mappingContext) {
102 | Object source = mappingContext.getSource();
103 | Class> sourceType = source.getClass();
104 | if (sourceType.equals(String.class))
105 | return LocalDateTime.parse((String) source,
106 | config.getDateTimeFormatter());
107 | return convertInstant(mappingContext).atZone(config.getZoneId()).toLocalDateTime();
108 | }
109 |
110 | private ZonedDateTime convertZonedDateTime(MappingContext, ?> mappingContext) {
111 | Object source = mappingContext.getSource();
112 | Class> sourceType = source.getClass();
113 | if (sourceType.equals(String.class))
114 | return ZonedDateTime.parse((String) source,
115 | config.getDateTimeOffsetFormatter());
116 | return convertInstant(mappingContext).atZone(config.getZoneId());
117 | }
118 |
119 | private OffsetDateTime convertOffsetDateTime(MappingContext, ?> mappingContext) {
120 | Object source = mappingContext.getSource();
121 | Class> sourceType = source.getClass();
122 | if (sourceType.equals(String.class))
123 | return OffsetDateTime.parse((String) source,
124 | config.getDateTimeOffsetFormatter());
125 | return convertInstant(mappingContext).atZone(config.getZoneId()).toOffsetDateTime();
126 | }
127 |
128 | private Instant convertInstant(MappingContext, ?> mappingContext) {
129 | Object source = mappingContext.getSource();
130 | Class> sourceType = source.getClass();
131 | if (sourceType.equals(String.class))
132 | return LocalDateTime.parse((String) source,
133 | config.getDateTimeFormatter())
134 | .atZone(config.getZoneId()).toInstant();
135 | else if (Date.class.isAssignableFrom(sourceType))
136 | return Instant.ofEpochMilli(((Date) source).getTime());
137 | else if (Calendar.class.isAssignableFrom(sourceType))
138 | return Instant.ofEpochMilli(((Calendar) source).getTime().getTime());
139 | else if (Number.class.isAssignableFrom(sourceType))
140 | return Instant.ofEpochMilli(((Number) source).longValue());
141 | else
142 | throw new Errors().addMessage("Unsupported mapping types[%s->%s]",
143 | sourceType.getName(), mappingContext.getDestinationType().getName())
144 | .toMappingException();
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/FromInstantConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import static org.testng.Assert.assertEquals;
4 | import static org.testng.Assert.assertNull;
5 |
6 | import java.math.BigDecimal;
7 | import java.math.BigInteger;
8 | import java.time.Instant;
9 | import java.time.ZoneOffset;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 | import org.modelmapper.spi.ConditionalConverter;
13 | import org.testng.annotations.BeforeMethod;
14 | import org.testng.annotations.Test;
15 |
16 | @Test
17 | public class FromInstantConverterTest {
18 |
19 | private Jsr310ModuleConfig config;
20 | private ConditionalConverter converter;
21 |
22 | @BeforeMethod
23 | public void setUp() {
24 | config = Jsr310ModuleConfig.builder()
25 | .zoneId(ZoneOffset.UTC)
26 | .build();
27 | converter = TestHelper.unsafe(new FromTemporalConverter(config));
28 | }
29 |
30 | public void shouldConvertToDefaultString() {
31 | Instant source = TestHelper.instantOf(2018, 1, 1);
32 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, Instant.class, String.class));
33 | assertEquals(dateText, "2018-01-01 00:00:00");
34 | }
35 |
36 | public void shouldConvertToStringWithPattern() {
37 | config.setDateTimePattern("yyyy-MM-dd HH:mm:ss.SSS");
38 | Instant source = TestHelper.instantOf(2018, 1, 1);
39 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, Instant.class, String.class));
40 | assertEquals(dateText, "2018-01-01 00:00:00.000");
41 | }
42 |
43 | public void shouldConvertToLong() {
44 | Instant source = TestHelper.instantOf(2018, 1, 1);
45 | long timestamp = (Long) converter.convert(TestHelper.unsafeMappingContext(source, Instant.class, Long.class));
46 | assertEquals(timestamp, 1514764800000L);
47 | }
48 |
49 | public void shouldConvertToBigDecimal() {
50 | Instant source = TestHelper.instantOf(2018, 1, 1);
51 | BigDecimal timestamp = (BigDecimal) converter.convert(TestHelper.unsafeMappingContext(source, Instant.class, BigDecimal.class));
52 | assertEquals(timestamp.longValue(), 1514764800000L);
53 | }
54 |
55 | public void shouldConvertToBigInteger() {
56 | Instant source = TestHelper.instantOf(2018, 1, 1);
57 | BigInteger timestamp = (BigInteger) converter.convert(TestHelper.unsafeMappingContext(source, Instant.class, BigInteger.class));
58 | assertEquals(timestamp.longValue(), 1514764800000L);
59 | }
60 |
61 | public void shouldConvertToDate() {
62 | Instant source = TestHelper.instantOf(2018, 1, 1);
63 | Date timestamp = (Date) converter.convert(TestHelper.unsafeMappingContext(source, Instant.class, Date.class));
64 | assertEquals(timestamp.getTime(), 1514764800000L);
65 | }
66 |
67 | public void shouldConvertToCalendar() {
68 | Instant source = TestHelper.instantOf(2018, 1, 1);
69 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(source, Instant.class, Calendar.class));
70 | assertEquals(timestamp.getTime().getTime(), 1514764800000L);
71 | }
72 |
73 | public void shouldConvertNull() {
74 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(null, Instant.class, Calendar.class));
75 | assertNull(timestamp);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/FromLocalDateConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import static org.testng.Assert.assertEquals;
4 | import static org.testng.Assert.assertNull;
5 |
6 | import java.math.BigDecimal;
7 | import java.math.BigInteger;
8 | import java.time.LocalDate;
9 | import java.time.ZoneOffset;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 | import org.modelmapper.spi.ConditionalConverter;
13 | import org.testng.annotations.BeforeMethod;
14 | import org.testng.annotations.Test;
15 |
16 | @Test
17 | public class FromLocalDateConverterTest {
18 |
19 | private Jsr310ModuleConfig config;
20 | private ConditionalConverter converter;
21 |
22 | @BeforeMethod
23 | public void setUp() {
24 | config = Jsr310ModuleConfig.builder()
25 | .zoneId(ZoneOffset.UTC)
26 | .build();
27 | converter = TestHelper.unsafe(new FromTemporalConverter(config));
28 | }
29 |
30 | public void shouldConvertToDefaultString() {
31 | LocalDate source = TestHelper.instantOf(2018, 1, 1)
32 | .atZone(ZoneOffset.UTC)
33 | .toLocalDate();
34 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, LocalDate.class, String.class));
35 | assertEquals(dateText, "2018-01-01");
36 | }
37 |
38 | public void shouldConvertToStringWithPattern() {
39 | config.setDatePattern("yyyy/MM/dd");
40 | LocalDate source = TestHelper.instantOf(2018, 1, 1)
41 | .atZone(ZoneOffset.UTC)
42 | .toLocalDate();
43 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, LocalDate.class, String.class));
44 | assertEquals(dateText, "2018/01/01");
45 | }
46 |
47 | public void shouldConvertToLong() {
48 | LocalDate source = TestHelper.instantOf(2018, 1, 1)
49 | .atZone(ZoneOffset.UTC)
50 | .toLocalDate();
51 | long timestamp = (Long) converter.convert(TestHelper.unsafeMappingContext(source, LocalDate.class, Long.class));
52 | assertEquals(timestamp, 1514764800000L);
53 | }
54 |
55 | public void shouldConvertToBigDecimal() {
56 | LocalDate source = TestHelper.instantOf(2018, 1, 1)
57 | .atZone(ZoneOffset.UTC)
58 | .toLocalDate();
59 | BigDecimal timestamp = (BigDecimal) converter.convert(TestHelper.unsafeMappingContext(source, LocalDate.class, BigDecimal.class));
60 | assertEquals(timestamp.longValue(), 1514764800000L);
61 | }
62 |
63 | public void shouldConvertToBigInteger() {
64 | LocalDate source = TestHelper.instantOf(2018, 1, 1)
65 | .atZone(ZoneOffset.UTC)
66 | .toLocalDate();
67 | BigInteger timestamp = (BigInteger) converter.convert(TestHelper.unsafeMappingContext(source, LocalDate.class, BigInteger.class));
68 | assertEquals(timestamp.longValue(), 1514764800000L);
69 | }
70 |
71 | public void shouldConvertToDate() {
72 | LocalDate source = TestHelper.instantOf(2018, 1, 1)
73 | .atZone(ZoneOffset.UTC)
74 | .toLocalDate();
75 | Date timestamp = (Date) converter.convert(TestHelper.unsafeMappingContext(source, LocalDate.class, Date.class));
76 | assertEquals(timestamp.getTime(), 1514764800000L);
77 | }
78 |
79 | public void shouldConvertToCalendar() {
80 | LocalDate source = TestHelper.instantOf(2018, 1, 1)
81 | .atZone(ZoneOffset.UTC)
82 | .toLocalDate();
83 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(source, LocalDate.class, Calendar.class));
84 | assertEquals(timestamp.getTime().getTime(), 1514764800000L);
85 | }
86 |
87 | public void shouldConvertNull() {
88 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(null, LocalDate.class, Calendar.class));
89 | assertNull(timestamp);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/FromLocalDateTimeConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import static org.testng.Assert.assertEquals;
4 | import static org.testng.Assert.assertNull;
5 |
6 | import java.math.BigDecimal;
7 | import java.math.BigInteger;
8 | import java.time.LocalDateTime;
9 | import java.time.ZoneOffset;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 | import org.modelmapper.spi.ConditionalConverter;
13 | import org.testng.annotations.BeforeMethod;
14 | import org.testng.annotations.Test;
15 |
16 | @Test
17 | public class FromLocalDateTimeConverterTest {
18 |
19 | private Jsr310ModuleConfig config;
20 | private ConditionalConverter converter;
21 |
22 | @BeforeMethod
23 | public void setUp() {
24 | config = Jsr310ModuleConfig.builder()
25 | .zoneId(ZoneOffset.UTC)
26 | .build();
27 | converter = TestHelper.unsafe(new FromTemporalConverter(config));
28 | }
29 |
30 | public void shouldConvertToDefaultString() {
31 | LocalDateTime source = TestHelper.instantOf(2018, 1, 1)
32 | .atZone(ZoneOffset.UTC)
33 | .toLocalDateTime();
34 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, LocalDateTime.class, String.class));
35 | assertEquals(dateText, "2018-01-01 00:00:00");
36 | }
37 |
38 | public void shouldConvertToStringWithPattern() {
39 | config.setDateTimePattern("yyyy-MM-dd HH:mm:ss.SSS");
40 | LocalDateTime source = TestHelper.instantOf(2018, 1, 1)
41 | .atZone(ZoneOffset.UTC)
42 | .toLocalDateTime();
43 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, LocalDateTime.class, String.class));
44 | assertEquals(dateText, "2018-01-01 00:00:00.000");
45 | }
46 |
47 | public void shouldConvertToLong() {
48 | LocalDateTime source = TestHelper.instantOf(2018, 1, 1)
49 | .atZone(ZoneOffset.UTC)
50 | .toLocalDateTime();
51 | long timestamp = (Long) converter.convert(TestHelper.unsafeMappingContext(source, LocalDateTime.class, Long.class));
52 | assertEquals(timestamp, 1514764800000L);
53 | }
54 |
55 | public void shouldConvertToBigDecimal() {
56 | LocalDateTime source = TestHelper.instantOf(2018, 1, 1)
57 | .atZone(ZoneOffset.UTC)
58 | .toLocalDateTime();
59 | BigDecimal timestamp = (BigDecimal) converter.convert(TestHelper.unsafeMappingContext(source, LocalDateTime.class, BigDecimal.class));
60 | assertEquals(timestamp.longValue(), 1514764800000L);
61 | }
62 |
63 | public void shouldConvertToBigInteger() {
64 | LocalDateTime source = TestHelper.instantOf(2018, 1, 1)
65 | .atZone(ZoneOffset.UTC)
66 | .toLocalDateTime();
67 | BigInteger timestamp = (BigInteger) converter.convert(TestHelper.unsafeMappingContext(source, LocalDateTime.class, BigInteger.class));
68 | assertEquals(timestamp.longValue(), 1514764800000L);
69 | }
70 |
71 | public void shouldConvertToDate() {
72 | LocalDateTime source = TestHelper.instantOf(2018, 1, 1)
73 | .atZone(ZoneOffset.UTC)
74 | .toLocalDateTime();
75 | Date timestamp = (Date) converter.convert(TestHelper.unsafeMappingContext(source, LocalDateTime.class, Date.class));
76 | assertEquals(timestamp.getTime(), 1514764800000L);
77 | }
78 |
79 | public void shouldConvertToCalendar() {
80 | LocalDateTime source = TestHelper.instantOf(2018, 1, 1)
81 | .atZone(ZoneOffset.UTC)
82 | .toLocalDateTime();
83 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(source, LocalDateTime.class, Calendar.class));
84 | assertEquals(timestamp.getTime().getTime(), 1514764800000L);
85 | }
86 |
87 | public void shouldConvertNull() {
88 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(null, LocalDateTime.class, Calendar.class));
89 | assertNull(timestamp);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/FromOffsetDateTimeConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import org.modelmapper.spi.ConditionalConverter;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import java.math.BigDecimal;
8 | import java.math.BigInteger;
9 | import java.time.LocalDateTime;
10 | import java.time.OffsetDateTime;
11 | import java.time.ZoneId;
12 | import java.time.ZoneOffset;
13 | import java.util.Calendar;
14 | import java.util.Date;
15 |
16 | import static org.testng.Assert.assertEquals;
17 | import static org.testng.Assert.assertNull;
18 |
19 | @Test
20 | public class FromOffsetDateTimeConverterTest {
21 |
22 | private Jsr310ModuleConfig config;
23 | private ConditionalConverter converter;
24 |
25 | @BeforeMethod
26 | public void setUp() {
27 | config = Jsr310ModuleConfig.builder()
28 | .zoneId(ZoneOffset.UTC)
29 | .build();
30 | converter = TestHelper.unsafe(new FromTemporalConverter(config));
31 | }
32 |
33 | public void shouldConvertToDefaultString() {
34 | OffsetDateTime source = TestHelper.instantOf(2018, 1, 1)
35 | .atZone(ZoneOffset.UTC)
36 | .toOffsetDateTime();
37 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, OffsetDateTime.class, String.class));
38 | assertEquals(dateText, "2018-01-01 00:00:00Z");
39 | }
40 |
41 | public void shouldConvertZonedTimeToDefaultString() {
42 | OffsetDateTime source = TestHelper.instantOf(2018, 1, 1)
43 | .atZone(ZoneId.of("-05:00"))
44 | .toOffsetDateTime();
45 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, OffsetDateTime.class, String.class));
46 | assertEquals(dateText, "2017-12-31 19:00:00-05");
47 | }
48 |
49 | public void shouldConvertToLong() {
50 | OffsetDateTime source = TestHelper.instantOf(2018, 1, 1)
51 | .atZone(ZoneOffset.UTC)
52 | .toOffsetDateTime();
53 | long timestamp = (Long) converter.convert(TestHelper.unsafeMappingContext(source, OffsetDateTime.class, Long.class));
54 | assertEquals(timestamp, 1514764800000L);
55 | }
56 |
57 | public void shouldConvertToBigDecimal() {
58 | OffsetDateTime source = TestHelper.instantOf(2018, 1, 1)
59 | .atZone(ZoneOffset.UTC)
60 | .toOffsetDateTime();
61 | BigDecimal timestamp = (BigDecimal) converter.convert(TestHelper.unsafeMappingContext(source, OffsetDateTime.class, BigDecimal.class));
62 | assertEquals(timestamp.longValue(), 1514764800000L);
63 | }
64 |
65 | public void shouldConvertToBigInteger() {
66 | OffsetDateTime source = TestHelper.instantOf(2018, 1, 1)
67 | .atZone(ZoneOffset.UTC)
68 | .toOffsetDateTime();
69 | BigInteger timestamp = (BigInteger) converter.convert(TestHelper.unsafeMappingContext(source, OffsetDateTime.class, BigInteger.class));
70 | assertEquals(timestamp.longValue(), 1514764800000L);
71 | }
72 |
73 | public void shouldConvertToDate() {
74 | OffsetDateTime source = TestHelper.instantOf(2018, 1, 1)
75 | .atZone(ZoneOffset.UTC)
76 | .toOffsetDateTime();
77 | Date timestamp = (Date) converter.convert(TestHelper.unsafeMappingContext(source, OffsetDateTime.class, Date.class));
78 | assertEquals(timestamp.getTime(), 1514764800000L);
79 | }
80 |
81 | public void shouldConvertToCalendar() {
82 | OffsetDateTime source = TestHelper.instantOf(2018, 1, 1)
83 | .atZone(ZoneOffset.UTC)
84 | .toOffsetDateTime();
85 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(source, OffsetDateTime.class, Calendar.class));
86 | assertEquals(timestamp.getTime().getTime(), 1514764800000L);
87 | }
88 |
89 | public void shouldConvertNull() {
90 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(null, OffsetDateTime.class, Calendar.class));
91 | assertNull(timestamp);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/FromZonedDateTimeConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import org.modelmapper.spi.ConditionalConverter;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import java.math.BigDecimal;
8 | import java.math.BigInteger;
9 | import java.time.ZoneId;
10 | import java.time.ZoneOffset;
11 | import java.time.ZonedDateTime;
12 | import java.util.Calendar;
13 | import java.util.Date;
14 |
15 | import static org.testng.Assert.assertEquals;
16 | import static org.testng.Assert.assertNull;
17 |
18 | @Test
19 | public class FromZonedDateTimeConverterTest {
20 |
21 | private Jsr310ModuleConfig config;
22 | private ConditionalConverter converter;
23 |
24 | @BeforeMethod
25 | public void setUp() {
26 | config = Jsr310ModuleConfig.builder()
27 | .zoneId(ZoneId.of("-05:00"))
28 | .build();
29 | converter = TestHelper.unsafe(new FromTemporalConverter(config));
30 | }
31 |
32 | public void shouldConvertToDefaultString() {
33 | ZonedDateTime source = TestHelper.instantOf(2018, 1, 1).atZone(ZoneOffset.UTC);
34 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, ZonedDateTime.class, String.class));
35 | assertEquals(dateText, "2018-01-01 00:00:00Z");
36 | }
37 |
38 | public void shouldConvertToStringWithPattern() {
39 | config.setDateTimeOffsetPattern("yyyy-MM-dd HH:mm:ss.SSSX");
40 | ZonedDateTime source = TestHelper.instantOf(2018, 1, 1).atZone(ZoneOffset.UTC);
41 | String dateText = (String) converter.convert(TestHelper.unsafeMappingContext(source, ZonedDateTime.class, String.class));
42 | assertEquals(dateText, "2018-01-01 00:00:00.000Z");
43 | }
44 |
45 | public void shouldConvertToLong() {
46 | ZonedDateTime source = TestHelper.instantOf(2018, 1, 1).atZone(ZoneOffset.UTC);
47 | long timestamp = (Long) converter.convert(TestHelper.unsafeMappingContext(source, ZonedDateTime.class, Long.class));
48 | assertEquals(timestamp, 1514764800000L);
49 | }
50 |
51 | public void shouldConvertToBigDecimal() {
52 | ZonedDateTime source = TestHelper.instantOf(2018, 1, 1).atZone(ZoneOffset.UTC);
53 | BigDecimal timestamp = (BigDecimal) converter.convert(TestHelper.unsafeMappingContext(source, ZonedDateTime.class, BigDecimal.class));
54 | assertEquals(timestamp.longValue(), 1514764800000L);
55 | }
56 |
57 | public void shouldConvertToBigInteger() {
58 | ZonedDateTime source = TestHelper.instantOf(2018, 1, 1).atZone(ZoneOffset.UTC);
59 | BigInteger timestamp = (BigInteger) converter.convert(TestHelper.unsafeMappingContext(source, ZonedDateTime.class, BigInteger.class));
60 | assertEquals(timestamp.longValue(), 1514764800000L);
61 | }
62 |
63 | public void shouldConvertToDate() {
64 | ZonedDateTime source = TestHelper.instantOf(2018, 1, 1).atZone(ZoneOffset.UTC);
65 | Date timestamp = (Date) converter.convert(TestHelper.unsafeMappingContext(source, ZonedDateTime.class, Date.class));
66 | assertEquals(timestamp.getTime(), 1514764800000L);
67 | }
68 |
69 | public void shouldConvertToCalendar() {
70 | ZonedDateTime source = TestHelper.instantOf(2018, 1, 1).atZone(ZoneOffset.UTC);
71 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(source, ZonedDateTime.class, Calendar.class));
72 | assertEquals(timestamp.getTime().getTime(), 1514764800000L);
73 | }
74 |
75 | public void shouldConvertNull() {
76 | Calendar timestamp = (Calendar) converter.convert(TestHelper.unsafeMappingContext(null, ZonedDateTime.class, Calendar.class));
77 | assertNull(timestamp);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/Jsr310ModuleTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import java.time.Instant;
4 | import java.time.ZoneOffset;
5 | import lombok.Data;
6 | import org.modelmapper.ModelMapper;
7 | import org.testng.annotations.BeforeMethod;
8 | import org.testng.annotations.Test;
9 |
10 | import static org.testng.Assert.assertEquals;
11 |
12 | @Test
13 | public class Jsr310ModuleTest {
14 |
15 | @Data
16 | private static class StringWrapper {
17 | private String date;
18 | }
19 |
20 | @Data
21 | private static class InstantWrapper {
22 | private Instant date;
23 | }
24 |
25 | private ModelMapper modelMapper;
26 |
27 | @BeforeMethod
28 | public void setUp() {
29 | Jsr310ModuleConfig config = Jsr310ModuleConfig.builder()
30 | .zoneId(ZoneOffset.UTC)
31 | .build();
32 | modelMapper = new ModelMapper()
33 | .registerModule(new Jsr310Module(config));
34 | }
35 |
36 | public void shouldMapStringToInstant() {
37 | StringWrapper source = new StringWrapper();
38 | source.setDate("2018-01-01 00:00:00");
39 | InstantWrapper destination = modelMapper.map(source, InstantWrapper.class);
40 | assertEquals(destination.getDate().toEpochMilli(), 1514764800000L);
41 | }
42 |
43 | public void shouldMapInstantToString() {
44 | InstantWrapper source = new InstantWrapper();
45 | source.setDate(TestHelper.instantOf(2018, 1, 1));
46 | StringWrapper destination = modelMapper.map(source, StringWrapper.class);
47 | assertEquals(destination.getDate(), "2018-01-01 00:00:00");
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/TestHelper.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import java.time.Instant;
4 | import org.modelmapper.internal.MappingContextImpl;
5 | import org.modelmapper.spi.ConditionalConverter;
6 | import org.modelmapper.spi.MappingContext;
7 |
8 | public class TestHelper {
9 | public static MappingContext mappingContext(S source, Class sourceType, Class destinationType) {
10 | return new MappingContextImpl<>(source ,sourceType, null,
11 | destinationType,null, "", null);
12 | }
13 | public static MappingContext unsafeMappingContext(S source, Class sourceType, Class destinationType) {
14 | MappingContext, ?> mappingContext = mappingContext(source ,sourceType, destinationType);
15 | return unsafe(mappingContext);
16 | }
17 |
18 | @SuppressWarnings("unchecked")
19 | public static MappingContext unsafe(MappingContext, ?> mappingContext) {
20 | return (MappingContext) mappingContext;
21 | }
22 |
23 | @SuppressWarnings("unchecked")
24 | public static ConditionalConverter unsafe(ConditionalConverter, ?> converter) {
25 | return (ConditionalConverter) converter;
26 | }
27 |
28 | public static Instant instantOf(int year, int month, int day) {
29 | return Instant.parse(String.format("%04d-%02d-%02dT00:00:00Z", year, month, day));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/ToInstantConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import java.math.BigDecimal;
4 | import java.math.BigInteger;
5 | import java.time.Instant;
6 | import java.time.ZoneOffset;
7 | import java.util.Calendar;
8 | import java.util.Date;
9 | import org.modelmapper.spi.ConditionalConverter;
10 | import org.testng.annotations.BeforeMethod;
11 | import org.testng.annotations.Test;
12 |
13 | import static org.testng.Assert.assertEquals;
14 | import static org.testng.Assert.assertNull;
15 |
16 | @Test
17 | public class ToInstantConverterTest {
18 |
19 | private Jsr310ModuleConfig config;
20 | private ConditionalConverter converter;
21 |
22 | @BeforeMethod
23 | public void setUp() {
24 | config = Jsr310ModuleConfig.builder()
25 | .zoneId(ZoneOffset.UTC)
26 | .build();
27 | converter = TestHelper.unsafe(new ToTemporalConverter(config));
28 | }
29 |
30 | public void shouldConvertStringWithDefaultPattern() {
31 | Instant instant = (Instant) converter.convert(TestHelper.unsafeMappingContext(
32 | "2018-01-01 00:00:00", String.class, Instant.class));
33 | assertEquals(instant.toEpochMilli(), 1514764800000L);
34 | }
35 |
36 | public void shouldConvertStringWithCustomPattern() {
37 | config.setDateTimePattern("yyyy-MM-dd HH:mm:ss.SSS");
38 | Instant instant = (Instant) converter.convert(TestHelper.unsafeMappingContext(
39 | "2018-01-01 00:00:00.000", String.class, Instant.class));
40 | assertEquals(instant.toEpochMilli(), 1514764800000L);
41 | }
42 |
43 | public void shouldConvertLong() {
44 | Instant instant = (Instant) converter.convert(TestHelper.unsafeMappingContext(
45 | 1514764800000L, Long.class, Instant.class));
46 | assertEquals(instant.toEpochMilli(), 1514764800000L);
47 | }
48 |
49 | public void shouldConvertPrimitiveLong() {
50 | Instant instant = (Instant) converter.convert(TestHelper.unsafeMappingContext(
51 | 1514764800000L, Long.TYPE, Instant.class));
52 | assertEquals(instant.toEpochMilli(), 1514764800000L);
53 | }
54 |
55 | public void shouldConvertBigDecimal() {
56 | Instant instant = (Instant) converter.convert(TestHelper.unsafeMappingContext(
57 | new BigDecimal("1514764800000"), BigDecimal.class, Instant.class));
58 | assertEquals(instant.toEpochMilli(), 1514764800000L);
59 | }
60 |
61 | public void shouldConvertBigInteger() {
62 | Instant instant = (Instant) converter.convert(TestHelper.unsafeMappingContext(
63 | new BigInteger("1514764800000"), BigInteger.class, Instant.class));
64 | assertEquals(instant.toEpochMilli(), 1514764800000L);
65 | }
66 |
67 | public void shouldConvertDate() {
68 | Instant instant = (Instant) converter.convert(TestHelper.unsafeMappingContext(
69 | new Date(1514764800000L), Date.class, Instant.class));
70 | assertEquals(instant.toEpochMilli(), 1514764800000L);
71 | }
72 |
73 | public void shouldConvertCalendar() {
74 | Calendar calendar = Calendar.getInstance();
75 | calendar.setTimeInMillis(1514764800000L);
76 | Instant instant = (Instant) converter.convert(TestHelper.unsafeMappingContext(
77 | calendar, Calendar.class, Instant.class));
78 | assertEquals(instant.toEpochMilli(), 1514764800000L);
79 | }
80 |
81 | public void shouldConvertNull() {
82 | Instant timestamp = (Instant) converter.convert(TestHelper.unsafeMappingContext(
83 | null, Date.class, Instant.class));
84 | assertNull(timestamp);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/ToLocalDateConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import static org.testng.Assert.assertEquals;
4 | import static org.testng.Assert.assertNull;
5 |
6 | import java.math.BigDecimal;
7 | import java.math.BigInteger;
8 | import java.time.LocalDate;
9 | import java.time.ZoneOffset;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 | import org.modelmapper.spi.ConditionalConverter;
13 | import org.testng.annotations.BeforeMethod;
14 | import org.testng.annotations.Test;
15 |
16 | @Test
17 | public class ToLocalDateConverterTest {
18 |
19 | private Jsr310ModuleConfig config;
20 | private ConditionalConverter converter;
21 |
22 | @BeforeMethod
23 | public void setUp() {
24 | config = Jsr310ModuleConfig.builder()
25 | .zoneId(ZoneOffset.UTC)
26 | .build();
27 | converter = TestHelper.unsafe(new ToTemporalConverter(config));
28 | }
29 |
30 | public void shouldConvertStringWithDefaultPattern() {
31 | LocalDate localDate = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
32 | "2018-01-01", String.class, LocalDate.class));
33 | assertEquals(localDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
34 | }
35 |
36 | public void shouldConvertStringWithCustomPattern() {
37 | config.setDatePattern("yyyy/MM/dd");
38 | LocalDate localDate = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
39 | "2018/01/01", String.class, LocalDate.class));
40 | assertEquals(localDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
41 | }
42 |
43 | public void shouldConvertLong() {
44 | LocalDate localDate = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
45 | 1514764800000L, Long.class, LocalDate.class));
46 | assertEquals(localDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
47 | }
48 |
49 | public void shouldConvertPrimitiveLong() {
50 | LocalDate localDate = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
51 | 1514764800000L, Long.TYPE, LocalDate.class));
52 | assertEquals(localDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
53 | }
54 |
55 | public void shouldConvertBigDecimal() {
56 | LocalDate localDate = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
57 | new BigDecimal("1514764800000"), BigDecimal.class, LocalDate.class));
58 | assertEquals(localDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
59 | }
60 |
61 | public void shouldConvertBigInteger() {
62 | LocalDate localDate = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
63 | new BigInteger("1514764800000"), BigInteger.class, LocalDate.class));
64 | assertEquals(localDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
65 | }
66 |
67 | public void shouldConvertDate() {
68 | LocalDate localDate = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
69 | new Date(1514764800000L), Date.class, LocalDate.class));
70 | assertEquals(localDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
71 | }
72 |
73 | public void shouldConvertCalendar() {
74 | Calendar calendar = Calendar.getInstance();
75 | calendar.setTimeInMillis(1514764800000L);
76 | LocalDate localDate = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
77 | calendar, Calendar.class, LocalDate.class));
78 | assertEquals(localDate.atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
79 | }
80 |
81 | public void shouldConvertNull() {
82 | LocalDate timestamp = (LocalDate) converter.convert(TestHelper.unsafeMappingContext(
83 | null, Date.class, LocalDate.class));
84 | assertNull(timestamp);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/ToLocalDateTimeConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import static org.testng.Assert.assertEquals;
4 | import static org.testng.Assert.assertNull;
5 |
6 | import java.math.BigDecimal;
7 | import java.math.BigInteger;
8 | import java.time.LocalDateTime;
9 | import java.time.ZoneOffset;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 | import org.modelmapper.spi.ConditionalConverter;
13 | import org.testng.annotations.BeforeMethod;
14 | import org.testng.annotations.Test;
15 |
16 | @Test
17 | public class ToLocalDateTimeConverterTest {
18 |
19 | private Jsr310ModuleConfig config;
20 | private ConditionalConverter converter;
21 |
22 | @BeforeMethod
23 | public void setUp() {
24 | config = Jsr310ModuleConfig.builder()
25 | .zoneId(ZoneOffset.UTC)
26 | .build();
27 | converter = TestHelper.unsafe(new ToTemporalConverter(config));
28 | }
29 |
30 | public void shouldConvertStringWithDefaultPattern() {
31 | LocalDateTime localDateTime = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
32 | "2018-01-01 00:00:00", String.class, LocalDateTime.class));
33 | assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
34 | }
35 |
36 | public void shouldConvertStringWithCustomPattern() {
37 | config.setDateTimePattern("yyyy-MM-dd HH:mm:ss.SSS");
38 | LocalDateTime localDateTime = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
39 | "2018-01-01 00:00:00.000", String.class, LocalDateTime.class));
40 | assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
41 | }
42 |
43 | public void shouldConvertLong() {
44 | LocalDateTime localDateTime = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
45 | 1514764800000L, Long.class, LocalDateTime.class));
46 | assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
47 | }
48 |
49 | public void shouldConvertPrimitiveLong() {
50 | LocalDateTime localDateTime = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
51 | 1514764800000L, Long.TYPE, LocalDateTime.class));
52 | assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
53 | }
54 |
55 | public void shouldConvertBigDecimal() {
56 | LocalDateTime localDateTime = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
57 | new BigDecimal("1514764800000"), BigDecimal.class, LocalDateTime.class));
58 | assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
59 | }
60 |
61 | public void shouldConvertBigInteger() {
62 | LocalDateTime localDateTime = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
63 | new BigInteger("1514764800000"), BigInteger.class, LocalDateTime.class));
64 | assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
65 | }
66 |
67 | public void shouldConvertDate() {
68 | LocalDateTime localDateTime = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
69 | new Date(1514764800000L), Date.class, LocalDateTime.class));
70 | assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
71 | }
72 |
73 | public void shouldConvertCalendar() {
74 | Calendar calendar = Calendar.getInstance();
75 | calendar.setTimeInMillis(1514764800000L);
76 | LocalDateTime localDateTime = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
77 | calendar, Calendar.class, LocalDateTime.class));
78 | assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), 1514764800000L);
79 | }
80 |
81 | public void shouldConvertNull() {
82 | LocalDateTime timestamp = (LocalDateTime) converter.convert(TestHelper.unsafeMappingContext(
83 | null, Date.class, LocalDateTime.class));
84 | assertNull(timestamp);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/ToOffsetDateTimeConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import org.modelmapper.spi.ConditionalConverter;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import java.math.BigDecimal;
8 | import java.math.BigInteger;
9 | import java.time.OffsetDateTime;
10 | import java.time.ZoneOffset;
11 | import java.util.Calendar;
12 | import java.util.Date;
13 |
14 | import static org.testng.Assert.assertEquals;
15 | import static org.testng.Assert.assertNull;
16 |
17 | @Test
18 | public class ToOffsetDateTimeConverterTest {
19 |
20 | private Jsr310ModuleConfig config;
21 | private ConditionalConverter converter;
22 |
23 | @BeforeMethod
24 | public void setUp() {
25 | config = Jsr310ModuleConfig.builder()
26 | .zoneId(ZoneOffset.UTC)
27 | .build();
28 | converter = TestHelper.unsafe(new ToTemporalConverter(config));
29 | }
30 |
31 | public void shouldConvertStringWithDefaultPattern() {
32 | OffsetDateTime offsetDateTime = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
33 | "2018-01-01 00:00:00Z", String.class, OffsetDateTime.class));
34 | assertEquals(offsetDateTime.toInstant().toEpochMilli(), 1514764800000L);
35 | }
36 |
37 | public void shouldConvertZonedTimeStringWithDefaultPattern() {
38 | OffsetDateTime offsetDateTime = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
39 | "2017-12-31 19:00:00-05", String.class, OffsetDateTime.class));
40 | assertEquals(offsetDateTime.toInstant().toEpochMilli(), 1514764800000L);
41 | }
42 |
43 | public void shouldConvertLong() {
44 | OffsetDateTime offsetDateTime = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
45 | 1514764800000L, Long.class, OffsetDateTime.class));
46 | assertEquals(offsetDateTime.toInstant().toEpochMilli(), 1514764800000L);
47 | }
48 |
49 | public void shouldConvertPrimitiveLong() {
50 | OffsetDateTime offsetDateTime = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
51 | 1514764800000L, Long.TYPE, OffsetDateTime.class));
52 | assertEquals(offsetDateTime.toInstant().toEpochMilli(), 1514764800000L);
53 | }
54 |
55 | public void shouldConvertBigDecimal() {
56 | OffsetDateTime offsetDateTime = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
57 | new BigDecimal("1514764800000"), BigDecimal.class, OffsetDateTime.class));
58 | assertEquals(offsetDateTime.toInstant().toEpochMilli(), 1514764800000L);
59 | }
60 |
61 | public void shouldConvertBigInteger() {
62 | OffsetDateTime offsetDateTime = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
63 | new BigInteger("1514764800000"), BigInteger.class, OffsetDateTime.class));
64 | assertEquals(offsetDateTime.toInstant().toEpochMilli(), 1514764800000L);
65 | }
66 |
67 | public void shouldConvertDate() {
68 | OffsetDateTime offsetDateTime = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
69 | new Date(1514764800000L), Date.class, OffsetDateTime.class));
70 | assertEquals(offsetDateTime.toInstant().toEpochMilli(), 1514764800000L);
71 | }
72 |
73 | public void shouldConvertCalendar() {
74 | Calendar calendar = Calendar.getInstance();
75 | calendar.setTimeInMillis(1514764800000L);
76 | OffsetDateTime offsetDateTime = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
77 | calendar, Calendar.class, OffsetDateTime.class));
78 | assertEquals(offsetDateTime.toInstant().toEpochMilli(), 1514764800000L);
79 | }
80 |
81 | public void shouldConvertNull() {
82 | OffsetDateTime timestamp = (OffsetDateTime) converter.convert(TestHelper.unsafeMappingContext(
83 | null, Date.class, OffsetDateTime.class));
84 | assertNull(timestamp);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/datetime/src/test/java/org/modelmapper/module/jsr310/ToZonedDateTimeConverterTest.java:
--------------------------------------------------------------------------------
1 | package org.modelmapper.module.jsr310;
2 |
3 | import org.modelmapper.spi.ConditionalConverter;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import java.math.BigDecimal;
8 | import java.math.BigInteger;
9 | import java.time.ZoneId;
10 | import java.time.ZoneOffset;
11 | import java.time.ZonedDateTime;
12 | import java.util.Calendar;
13 | import java.util.Date;
14 |
15 | import static org.testng.Assert.assertEquals;
16 |
17 | @Test
18 | public class ToZonedDateTimeConverterTest {
19 |
20 | private Jsr310ModuleConfig config;
21 | private ConditionalConverter converter;
22 |
23 | @BeforeMethod
24 | public void setUp() {
25 | config = Jsr310ModuleConfig.builder()
26 | .zoneId(ZoneId.of("-05:00"))
27 | .build();
28 | converter = TestHelper.unsafe(new ToTemporalConverter(config));
29 | }
30 |
31 | public void shouldConvertStringWithDefaultPattern() {
32 | ZonedDateTime zonedDateTime = (ZonedDateTime) converter.convert(TestHelper.unsafeMappingContext(
33 | "2018-01-01 00:00:00Z", String.class, ZonedDateTime.class));
34 | assertEquals(zonedDateTime.toInstant().toEpochMilli(), 1514764800000L);
35 | }
36 |
37 |
38 | public void shouldConvertLong() {
39 | ZonedDateTime zonedDateTime = (ZonedDateTime) converter.convert(TestHelper.unsafeMappingContext(
40 | 1514764800000L, Long.class, ZonedDateTime.class));
41 | assertEquals(ZoneId.of("-05:00"), zonedDateTime.getZone());
42 | assertEquals(zonedDateTime.toInstant().toEpochMilli(), 1514764800000L);
43 | }
44 |
45 | public void shouldConvertPrimitiveLong() {
46 | ZonedDateTime zonedDateTime = (ZonedDateTime) converter.convert(TestHelper.unsafeMappingContext(
47 | 1514764800000L, Long.class, ZonedDateTime.class));
48 | assertEquals(zonedDateTime.toInstant().toEpochMilli(), 1514764800000L);
49 | }
50 |
51 | public void shouldConvertBigDecimal() {
52 | ZonedDateTime zonedDateTime = (ZonedDateTime) converter.convert(TestHelper.unsafeMappingContext(
53 | new BigDecimal("1514764800000"), BigDecimal.class, ZonedDateTime.class));
54 | assertEquals(zonedDateTime.toInstant().toEpochMilli(), 1514764800000L);
55 | }
56 |
57 | public void shouldConvertBigInteger() {
58 | ZonedDateTime zonedDateTime = (ZonedDateTime) converter.convert(TestHelper.unsafeMappingContext(
59 | new BigInteger("1514764800000"), BigInteger.class, ZonedDateTime.class));
60 | assertEquals(zonedDateTime.toInstant().toEpochMilli(), 1514764800000L);
61 | }
62 |
63 | public void shouldConvertDate() {
64 | ZonedDateTime zonedDateTime = (ZonedDateTime)converter.convert(TestHelper.unsafeMappingContext(
65 | new Date(1514764800000L), Date.class, ZonedDateTime.class));
66 | assertEquals(zonedDateTime.toInstant().toEpochMilli(), 1514764800000L);
67 | }
68 |
69 | public void shouldConvertCalendar() {
70 | Calendar calendar = Calendar.getInstance();
71 | calendar.setTimeInMillis(1514764800000L);
72 | ZonedDateTime zonedDateTime = (ZonedDateTime) converter.convert(TestHelper.unsafeMappingContext(
73 | calendar, Calendar.class, ZonedDateTime.class));
74 | assertEquals(zonedDateTime.toInstant().toEpochMilli(), 1514764800000L);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | org.sonatype.oss
6 | oss-parent
7 | 7
8 |
9 | org.modelmapper
10 | modelmapper-module-java8
11 | 1.2.4-SNAPSHOT
12 | pom
13 |
14 | datetime
15 | datatypes
16 |
17 | ModelMapper Module Java8
18 | ModelMapper Module for Java8
19 | http://modelmapper.org
20 | 2018
21 |
22 | 1.8
23 | 1.8
24 | 2.1.1
25 | 1.18.2
26 | 6.9.10
27 |
28 |
29 |
30 | Apache License, Version 2.0
31 | http://apache.org/licenses/LICENSE-2.0
32 | repo
33 |
34 |
35 |
36 |
37 | Chun Han Hsiao
38 | chhsiao90@gmail.com
39 |
40 |
41 |
42 | scm:git:git@github.com:chhsiao90/modelmapper-module-java8.git
43 | scm:git:git@github.com:chhsiao90/modelmapper-module-java8.git
44 | http://github.com/chhsiao90/modelmapper-module-java8/
45 |
46 |
47 | GitHub
48 | http://github.com/chhsiao90/modelmapper-module-java8/issues
49 |
50 |
51 |
52 | ModelMapper List
53 | http://groups.google.com/group/modelmapper/topics
54 | http://groups.google.com/group/modelmapper/subscribe
55 | http://groups.google.com/group/modelmapper/subscribe
56 | http://groups.google.com/group/modelmapper/post
57 |
58 |
59 |
60 |
61 | org.testng
62 | testng
63 | ${testng.version}
64 | test
65 |
66 |
67 |
68 |
69 |
70 | org.modelmapper
71 | modelmapper
72 | ${modelmapper.version}
73 |
74 |
75 | org.projectlombok
76 | lombok
77 | ${lombok.version}
78 | provided
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------