From a6ac4f3fd699ec71e7f4b1fcbe0f6e8061c3e1cf Mon Sep 17 00:00:00 2001 From: Ewald volkert Date: Thu, 15 Apr 2021 07:26:06 +0200 Subject: [PATCH] #2329 use fields for custom date formats with DateTimeFormatter in order to optimise its usage * GetDateTimeFormatterField ** a FieldReference that creates DateTimeFormatters for given dateFormat as mapper fields ** variableName is created using given dateFormat * AbstractJavaTimeToStringConversion provides GetDateTimeFormatterField as required helper field using DateTimeFormatter instances provided as mapper fields by GetDateTimeFormatterField * ConversionProvider might provide supporting fields directly * Refactoring moved/renamed BuiltInFieldReference, BuiltInConstuctorFragment to package model/common * MappingBuilderContext provides access to mapper support fields (that are independent of mapper methods) * MappingResolverImpl / MapperCreationProcessor process supporting fields provided by ConversionProvider * HelperMethod ** extended to supply additional template parameters to be more flexible in freemarker templates ** extended to support mapper field reference / constructor fragment * SupportingMappingMethod ** provide templateParameters to freemarker ** hashCode/equals base on name property instead of template name, as we use one specific template multiple times with different parameters generating multiple methods ** #getSafeField extracted to SupportingField * SupportingField ** removed hashCode/equals based on template name, as we use one specific template multiple times with different parameters generating multiple methods (superclass equals/hashcode is fine for that) ** added support for template parameters to be more flexible when compiling templates * Tests to verify DateTimeFormatter instance field creation --- .../AbstractJavaTimeToStringConversion.java | 19 +- .../conversion/ConversionProvider.java | 14 +- .../conversion/GetDateTimeFormatterField.java | 55 ++ .../internal/model/MappingBuilderContext.java | 10 +- .../model/SupportingConstructorFragment.java | 28 +- .../ap/internal/model/SupportingField.java | 59 +- .../model/SupportingMappingMethod.java | 53 +- .../ConstructorFragment.java} | 7 +- .../internal/model/common/FieldReference.java | 33 + .../builtin => common}/FinalField.java | 6 +- .../AbstractToXmlGregorianCalendar.java | 12 +- .../source/builtin/BuiltInFieldReference.java | 27 - .../model/source/builtin/BuiltInMethod.java | 11 +- ...NewDatatypeFactoryConstructorFragment.java | 4 +- .../processor/MapperCreationProcessor.java | 20 +- .../creation/MappingResolverImpl.java | 29 +- .../conversion/GetDateTimeFormatterField.ftl | 9 + .../{source/builtin => common}/FinalField.ftl | 0 ...PatternDateTimeFormatterGeneratedTest.java | 53 ++ .../java8time/Java8TimeConversionTest.java | 5 + .../Source.java | 40 ++ .../SourceTargetMapper.java | 29 + .../Target.java | 38 ++ .../java8time/SourceTargetMapperImpl.java | 640 ++++++++++++++++++ .../SourceTargetMapperImpl.java | 63 ++ 25 files changed, 1130 insertions(+), 134 deletions(-) create mode 100644 processor/src/main/java/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.java rename processor/src/main/java/org/mapstruct/ap/internal/model/{source/builtin/BuiltInConstructorFragment.java => common/ConstructorFragment.java} (58%) create mode 100644 processor/src/main/java/org/mapstruct/ap/internal/model/common/FieldReference.java rename processor/src/main/java/org/mapstruct/ap/internal/model/{source/builtin => common}/FinalField.java (77%) delete mode 100644 processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInFieldReference.java create mode 100644 processor/src/main/resources/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.ftl rename processor/src/main/resources/org/mapstruct/ap/internal/model/{source/builtin => common}/FinalField.ftl (100%) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8CustomPatternDateTimeFormatterGeneratedTest.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/Source.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/SourceTargetMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/Target.java create mode 100644 processor/src/test/resources/fixtures/org/mapstruct/ap/test/conversion/java8time/SourceTargetMapperImpl.java create mode 100644 processor/src/test/resources/fixtures/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/SourceTargetMapperImpl.java 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 e903c00e5..2f530618c 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 @@ -6,9 +6,11 @@ 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.Strings; @@ -38,10 +40,8 @@ public abstract class AbstractJavaTimeToStringConversion extends SimpleConversio } 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(); @@ -88,4 +88,15 @@ public abstract class AbstractJavaTimeToStringConversion extends SimpleConversio 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/ConversionProvider.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionProvider.java index 2ff73d348..31d4d2758 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 @@ -5,11 +5,14 @@ */ 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 @@ -49,4 +52,13 @@ public interface ConversionProvider { */ List getRequiredHelperMethods(ConversionContext conversionContext); + /** + * @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/GetDateTimeFormatterField.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.java new file mode 100644 index 000000000..052f2e722 --- /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/model/MappingBuilderContext.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java index a9d4fd091..fc82017a1 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 @@ -15,8 +15,6 @@ import java.util.function.Supplier; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.TypeElement; -import org.mapstruct.ap.internal.util.ElementUtils; -import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.FormattingParameters; @@ -28,8 +26,10 @@ 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.Services; +import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.spi.EnumMappingStrategy; import org.mapstruct.ap.spi.EnumTransformationStrategy; import org.mapstruct.ap.spi.MappingExclusionProvider; @@ -101,6 +101,8 @@ public class MappingBuilderContext { Supplier forger); Set getUsedSupportedMappings(); + + Set getUsedSupportedFields(); } private final TypeFactory typeFactory; @@ -241,6 +243,10 @@ public class MappingBuilderContext { return mappingResolver.getUsedSupportedMappings(); } + public Set getUsedSupportedFields() { + return mappingResolver.getUsedSupportedFields(); + } + /** * @param sourceType from which an automatic sub-mapping needs to be generated * @param targetType to which an automatic sub-mapping needs to be generated 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 index f25bbfca9..936a9a51b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingConstructorFragment.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingConstructorFragment.java @@ -9,9 +9,9 @@ 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; -import org.mapstruct.ap.internal.model.source.builtin.BuiltInConstructorFragment; /** * A mapper instance field, initialized as null @@ -20,13 +20,15 @@ import org.mapstruct.ap.internal.model.source.builtin.BuiltInConstructorFragment */ public class SupportingConstructorFragment extends ModelElement { + private final String variableName; private final String templateName; private final SupportingMappingMethod definingMethod; public SupportingConstructorFragment(SupportingMappingMethod definingMethod, - BuiltInConstructorFragment constructorFragment) { + ConstructorFragment constructorFragment, String variableName) { this.templateName = getTemplateNameForClass( constructorFragment.getClass() ); this.definingMethod = definingMethod; + this.variableName = variableName; } @Override @@ -43,10 +45,15 @@ public class SupportingConstructorFragment extends ModelElement { 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; } @@ -64,10 +71,12 @@ public class SupportingConstructorFragment extends ModelElement { } SupportingConstructorFragment other = (SupportingConstructorFragment) obj; + if ( !Objects.equals( variableName, other.variableName ) ) { + return false; + } if ( !Objects.equals( templateName, other.templateName ) ) { return false; } - return true; } @@ -80,4 +89,17 @@ public class SupportingConstructorFragment extends ModelElement { } } } + + 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 index a92f4c9df..caf6d6160 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingField.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingField.java @@ -5,10 +5,11 @@ */ package org.mapstruct.ap.internal.model; -import java.util.Objects; +import java.util.Map; import java.util.Set; -import org.mapstruct.ap.internal.model.source.builtin.BuiltInFieldReference; +import org.mapstruct.ap.internal.model.common.FieldReference; +import org.mapstruct.ap.internal.util.Strings; /** * supports the @@ -18,11 +19,14 @@ import org.mapstruct.ap.internal.model.source.builtin.BuiltInFieldReference; public class SupportingField extends Field { private final String templateName; + private final Map templateParameter; + private final SupportingMappingMethod definingMethod; - public SupportingField(SupportingMappingMethod definingMethod, BuiltInFieldReference fieldReference, String name) { + 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; } @@ -31,38 +35,14 @@ public class SupportingField extends Field { return templateName; } + public Map getTemplateParameter() { + return templateParameter; + } + public SupportingMappingMethod getDefiningMethod() { return definingMethod; } - @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; - } - SupportingField other = (SupportingField) obj; - - if ( !Objects.equals( templateName, other.templateName ) ) { - return false; - } - - return true; - } - public static void addAllFieldsIn(Set supportingMappingMethods, Set targets) { for ( SupportingMappingMethod supportingMappingMethod : supportingMappingMethods ) { Field field = supportingMappingMethod.getSupportingField(); @@ -71,4 +51,21 @@ public class SupportingField extends 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 index 756330e5d..9428454c1 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingMappingMethod.java @@ -5,14 +5,13 @@ */ 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.BuiltInFieldReference; import org.mapstruct.ap.internal.model.source.builtin.BuiltInMethod; import org.mapstruct.ap.internal.model.source.builtin.NewDatatypeFactoryConstructorFragment; -import org.mapstruct.ap.internal.util.Strings; /** * A mapping method which is not based on an actual method declared in the original mapper interface but is added as @@ -21,7 +20,7 @@ import org.mapstruct.ap.internal.util.Strings; * 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.source.builtin.FinalField} and + * {@link org.mapstruct.ap.internal.model.common.FinalField} and * {@link NewDatatypeFactoryConstructorFragment} * * @author Gunnar Morling @@ -32,49 +31,25 @@ public class SupportingMappingMethod extends MappingMethod { 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() ); - if ( method.getFieldReference() != null ) { - this.supportingField = getSafeField( method.getFieldReference(), existingFields ); - } - else { - this.supportingField = null; - } - if ( method.getConstructorFragment() != null ) { - this.supportingConstructorFragment = new SupportingConstructorFragment( - this, - method.getConstructorFragment() - ); - } - else { - this.supportingConstructorFragment = null; - } - } - - private Field getSafeField(BuiltInFieldReference ref, Set existingFields) { - String name = ref.getVariableName(); - for ( Field existingField : existingFields ) { - if ( existingField.getType().equals( ref.getType() ) ) { - // field type already exist, use that one - return existingField; - } - } - for ( Field existingField : existingFields ) { - if ( existingField.getVariableName().equals( ref.getVariableName() ) ) { - // field with name exist, however its a wrong type - name = Strings.getSafeVariableName( name, Field.getFieldNames( existingFields ) ); - } - } - return new SupportingField( this, ref, name ); + 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; } @@ -120,11 +95,15 @@ public class SupportingMappingMethod extends MappingMethod { return supportingConstructorFragment; } + public Map getTemplateParameter() { + return templateParameter; + } + @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ( ( templateName == null ) ? 0 : templateName.hashCode() ); + result = prime * result + ( ( getName() == null ) ? 0 : getName().hashCode() ); return result; } @@ -141,7 +120,7 @@ public class SupportingMappingMethod extends MappingMethod { } SupportingMappingMethod other = (SupportingMappingMethod) obj; - if ( !Objects.equals( templateName, other.templateName ) ) { + if ( !Objects.equals( getName(), other.getName() ) ) { return false; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInConstructorFragment.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConstructorFragment.java similarity index 58% rename from processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInConstructorFragment.java rename to processor/src/main/java/org/mapstruct/ap/internal/model/common/ConstructorFragment.java index ae8dbcc7c..89d292899 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInConstructorFragment.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConstructorFragment.java @@ -3,10 +3,11 @@ * * 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; +package org.mapstruct.ap.internal.model.common; /** - * ConstructorFragments are 'code snippets' added to the constructor to initialize fields used by {@link BuiltInMethod} + * ConstructorFragments are 'code snippets' added to the constructor to initialize fields used by + * BuiltInMethod/HelperMethod */ -public interface BuiltInConstructorFragment { +public interface ConstructorFragment { } 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 000000000..bf1f5be44 --- /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/source/builtin/FinalField.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/FinalField.java similarity index 77% rename from processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/FinalField.java rename to processor/src/main/java/org/mapstruct/ap/internal/model/common/FinalField.java index 5ce416711..c3e1ef1f3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/FinalField.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/FinalField.java @@ -3,16 +3,14 @@ * * 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.Type; +package org.mapstruct.ap.internal.model.common; /** * A mapper instance field, initialized as null * * @author Sjaak Derksen */ -public class FinalField implements BuiltInFieldReference { +public class FinalField implements FieldReference { private final Type type; private String variableName; 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 index 691d93d0f..7a2ac5588 100644 --- 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 @@ -5,17 +5,21 @@ */ 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.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.Strings; -import static org.mapstruct.ap.internal.util.Collections.asSet; - /** * @author Sjaak Derksen */ @@ -46,12 +50,12 @@ public abstract class AbstractToXmlGregorianCalendar extends BuiltInMethod { } @Override - public BuiltInFieldReference getFieldReference() { + public FieldReference getFieldReference() { return new FinalField( dataTypeFactoryType, Strings.decapitalize( DatatypeFactory.class.getSimpleName() ) ); } @Override - public BuiltInConstructorFragment getConstructorFragment() { + public ConstructorFragment getConstructorFragment() { return new NewDatatypeFactoryConstructorFragment( ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInFieldReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInFieldReference.java deleted file mode 100644 index 0eb15f289..000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInFieldReference.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 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.Type; - -/** - * reference used by BuiltInMethod to create an additional field in the mapper. - */ -public interface BuiltInFieldReference { - - /** - * - * @return variable name of the field - */ - String getVariableName(); - - /** - * - * @return type of the field - */ - Type getType(); - -} 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 e54a8ea4b..f46b20157 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 @@ -5,15 +5,20 @@ */ 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.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.MappingMethodOptions; @@ -21,8 +26,6 @@ import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods; 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 simple conversation doesn't suffice, e.g. as several lines of source code or a @@ -265,11 +268,11 @@ public abstract class BuiltInMethod implements Method { return MappingMethodOptions.empty(); } - public BuiltInFieldReference getFieldReference() { + public FieldReference getFieldReference() { return null; } - public BuiltInConstructorFragment getConstructorFragment() { + public ConstructorFragment getConstructorFragment() { return null; } 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 index a302b5937..e4f00f7d5 100644 --- 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 @@ -5,7 +5,9 @@ */ package org.mapstruct.ap.internal.model.source.builtin; -public class NewDatatypeFactoryConstructorFragment implements BuiltInConstructorFragment { +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/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java index c88714072..13e001017 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 @@ -22,9 +22,14 @@ 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 org.mapstruct.ap.internal.util.ElementUtils; -import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.ap.internal.gem.BuilderGem; +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.MapperGem; +import org.mapstruct.ap.internal.gem.MappingInheritanceStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; import org.mapstruct.ap.internal.model.BeanMappingMethod; import org.mapstruct.ap.internal.model.ContainerMappingMethod; import org.mapstruct.ap.internal.model.ContainerMappingMethodBuilder; @@ -50,18 +55,13 @@ 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.gem.BuilderGem; -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.MapperGem; -import org.mapstruct.ap.internal.gem.MappingInheritanceStrategyGem; -import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; 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.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; @@ -182,7 +182,7 @@ public class MapperCreationProcessor implements ModelElementProcessor fields = new ArrayList<>( mappingContext.getMapperReferences() ); - Set supportingFieldSet = new LinkedHashSet<>(); + Set supportingFieldSet = new LinkedHashSet<>(mappingContext.getUsedSupportedFields()); addAllFieldsIn( mappingContext.getUsedSupportedMappings(), supportingFieldSet ); fields.addAll( supportingFieldSet ); 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 ca2889e01..d9bd4d731 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 @@ -32,8 +32,6 @@ 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 org.mapstruct.ap.internal.util.ElementUtils; -import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.internal.conversion.ConversionProvider; import org.mapstruct.ap.internal.conversion.Conversions; @@ -49,6 +47,7 @@ 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; @@ -60,11 +59,13 @@ 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.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; /** * The one and only implementation of {@link MappingResolver}. The class has been split into an interface an @@ -98,6 +99,11 @@ public class MappingResolverImpl implements MappingResolver { */ private final Set usedSupportedMappings = new HashSet<>(); + /** + * Private fields which are added to map certain property types. + */ + private final Set usedSupportedFields = new HashSet<>(); + public MappingResolverImpl(FormattingMessager messager, ElementUtils elementUtils, TypeUtils typeUtils, TypeFactory typeFactory, List sourceModel, List mapperReferences, boolean verboseLogging) { @@ -144,6 +150,11 @@ public class MappingResolverImpl implements MappingResolver { return usedSupportedMappings; } + @Override + public Set getUsedSupportedFields() { + return usedSupportedFields; + } + private MapperReference findMapperReference(Method method) { for ( MapperReference ref : mapperReferences ) { if ( ref.getType().equals( method.getDeclaringMapper() ) ) { @@ -424,8 +435,20 @@ public class MappingResolverImpl implements MappingResolver { ); // add helper methods required in conversion + Set allUsedFields = new HashSet<>( mapperReferences ); + SupportingField.addAllFieldsIn( supportingMethodCandidates, allUsedFields ); + + for ( FieldReference helperField : conversionProvider.getRequiredHelperFields( ctx )) { + Field field = SupportingField.getSafeField( null, helperField, allUsedFields ); + allUsedFields.add( field ); + usedSupportedFields.add( field ); + } + for ( HelperMethod helperMethod : conversionProvider.getRequiredHelperMethods( ctx ) ) { - usedSupportedMappings.add( new SupportingMappingMethod( helperMethod ) ); + SupportingMappingMethod supportingMappingMethod = + new SupportingMappingMethod( helperMethod ); + SupportingField.addAllFieldsIn( Collections.asSet( supportingMappingMethod ), allUsedFields ); + usedSupportedMappings.add( supportingMappingMethod ); } Assignment conversion = conversionProvider.to( ctx ); 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 000000000..6efbe7f0f --- /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/source/builtin/FinalField.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/FinalField.ftl similarity index 100% rename from processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/FinalField.ftl rename to processor/src/main/resources/org/mapstruct/ap/internal/model/common/FinalField.ftl 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 000000000..443de8aab --- /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/Java8TimeConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8TimeConversionTest.java index bcd504564..b95b5d1ac 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 @@ -19,9 +19,11 @@ 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.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; @@ -32,6 +34,9 @@ import static org.assertj.core.api.Assertions.assertThat; @IssueKey("121") public class Java8TimeConversionTest { + @RegisterExtension + GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( SourceTargetMapper.class ); + private TimeZone originalTimeZone; @BeforeEach 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 000000000..f83721cbb --- /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 000000000..960ceec3b --- /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 000000000..7d265ba4a --- /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/resources/fixtures/org/mapstruct/ap/test/conversion/java8time/SourceTargetMapperImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/conversion/java8time/SourceTargetMapperImpl.java new file mode 100644 index 000000000..58beaa19d --- /dev/null +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/conversion/java8time/SourceTargetMapperImpl.java @@ -0,0 +1,640 @@ +/* + * Copyright MapStruct 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.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; +import javax.annotation.Generated; + +@Generated( + value = "org.mapstruct.ap.MappingProcessor", + date = "2021-05-15T18:24:04+0200", + comments = "version: , compiler: javac, environment: Java 1.8.0_275 (AdoptOpenJDK)" +) +public class SourceTargetMapperImpl implements SourceTargetMapper { + + private final DateTimeFormatter dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 = DateTimeFormatter.ofPattern( "dd.MM.yyyy HH:mm" ); + private final DateTimeFormatter dateTimeFormatter_HH_mm_168697690 = DateTimeFormatter.ofPattern( "HH:mm" ); + private final DateTimeFormatter dateTimeFormatter_dd_MM_yyyy_11900521056 = DateTimeFormatter.ofPattern( "dd.MM.yyyy" ); + private final DateTimeFormatter dateTimeFormatter_dd_MM_yyyy_HH_mm_z_01894582668 = DateTimeFormatter.ofPattern( "dd.MM.yyyy HH:mm z" ); + + @Override + public Target sourceToTarget(Source source) { + if ( source == null ) { + return null; + } + + Target target = new Target(); + + if ( source.getZonedDateTime() != null ) { + target.setZonedDateTime( dateTimeFormatter_dd_MM_yyyy_HH_mm_z_01894582668.format( source.getZonedDateTime() ) ); + } + if ( source.getLocalDateTime() != null ) { + target.setLocalDateTime( dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242.format( source.getLocalDateTime() ) ); + } + if ( source.getLocalDate() != null ) { + target.setLocalDate( dateTimeFormatter_dd_MM_yyyy_11900521056.format( source.getLocalDate() ) ); + } + if ( source.getLocalTime() != null ) { + target.setLocalTime( dateTimeFormatter_HH_mm_168697690.format( source.getLocalTime() ) ); + } + target.setForCalendarConversion( zonedDateTimeToCalendar( source.getForCalendarConversion() ) ); + if ( source.getForDateConversionWithZonedDateTime() != null ) { + target.setForDateConversionWithZonedDateTime( Date.from( source.getForDateConversionWithZonedDateTime().toInstant() ) ); + } + if ( source.getForDateConversionWithLocalDateTime() != null ) { + target.setForDateConversionWithLocalDateTime( Date.from( source.getForDateConversionWithLocalDateTime().toInstant( ZoneOffset.UTC ) ) ); + } + if ( source.getForDateConversionWithLocalDate() != null ) { + target.setForDateConversionWithLocalDate( Date.from( source.getForDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant() ) ); + } + if ( source.getForSqlDateConversionWithLocalDate() != null ) { + target.setForSqlDateConversionWithLocalDate( new java.sql.Date( source.getForSqlDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant().toEpochMilli() ) ); + } + if ( source.getForDateConversionWithInstant() != null ) { + target.setForDateConversionWithInstant( Date.from( source.getForDateConversionWithInstant() ) ); + } + if ( source.getForInstantConversionWithString() != null ) { + target.setForInstantConversionWithString( source.getForInstantConversionWithString().toString() ); + } + if ( source.getForPeriodConversionWithString() != null ) { + target.setForPeriodConversionWithString( source.getForPeriodConversionWithString().toString() ); + } + if ( source.getForDurationConversionWithString() != null ) { + target.setForDurationConversionWithString( source.getForDurationConversionWithString().toString() ); + } + + return target; + } + + @Override + public Target sourceToTargetDefaultMapping(Source source) { + if ( source == null ) { + return null; + } + + Target target = new Target(); + + if ( source.getZonedDateTime() != null ) { + target.setZonedDateTime( dateTimeFormatter_dd_MM_yyyy_HH_mm_z_01894582668.format( source.getZonedDateTime() ) ); + } + if ( source.getLocalDateTime() != null ) { + target.setLocalDateTime( dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242.format( source.getLocalDateTime() ) ); + } + if ( source.getLocalDate() != null ) { + target.setLocalDate( dateTimeFormatter_dd_MM_yyyy_11900521056.format( source.getLocalDate() ) ); + } + if ( source.getLocalTime() != null ) { + target.setLocalTime( dateTimeFormatter_HH_mm_168697690.format( source.getLocalTime() ) ); + } + target.setForCalendarConversion( zonedDateTimeToCalendar( source.getForCalendarConversion() ) ); + if ( source.getForDateConversionWithZonedDateTime() != null ) { + target.setForDateConversionWithZonedDateTime( Date.from( source.getForDateConversionWithZonedDateTime().toInstant() ) ); + } + if ( source.getForDateConversionWithLocalDateTime() != null ) { + target.setForDateConversionWithLocalDateTime( Date.from( source.getForDateConversionWithLocalDateTime().toInstant( ZoneOffset.UTC ) ) ); + } + if ( source.getForDateConversionWithLocalDate() != null ) { + target.setForDateConversionWithLocalDate( Date.from( source.getForDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant() ) ); + } + if ( source.getForSqlDateConversionWithLocalDate() != null ) { + target.setForSqlDateConversionWithLocalDate( new java.sql.Date( source.getForSqlDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant().toEpochMilli() ) ); + } + if ( source.getForDateConversionWithInstant() != null ) { + target.setForDateConversionWithInstant( Date.from( source.getForDateConversionWithInstant() ) ); + } + if ( source.getForInstantConversionWithString() != null ) { + target.setForInstantConversionWithString( source.getForInstantConversionWithString().toString() ); + } + if ( source.getForPeriodConversionWithString() != null ) { + target.setForPeriodConversionWithString( source.getForPeriodConversionWithString().toString() ); + } + if ( source.getForDurationConversionWithString() != null ) { + target.setForDurationConversionWithString( source.getForDurationConversionWithString().toString() ); + } + + return target; + } + + @Override + public Target sourceToTargetDateTimeMapped(Source source) { + if ( source == null ) { + return null; + } + + Target target = new Target(); + + if ( source.getZonedDateTime() != null ) { + target.setZonedDateTime( dateTimeFormatter_dd_MM_yyyy_HH_mm_z_01894582668.format( source.getZonedDateTime() ) ); + } + if ( source.getLocalDateTime() != null ) { + target.setLocalDateTime( DateTimeFormatter.ISO_LOCAL_DATE_TIME.format( source.getLocalDateTime() ) ); + } + if ( source.getLocalDate() != null ) { + target.setLocalDate( DateTimeFormatter.ISO_LOCAL_DATE.format( source.getLocalDate() ) ); + } + if ( source.getLocalTime() != null ) { + target.setLocalTime( DateTimeFormatter.ISO_LOCAL_TIME.format( source.getLocalTime() ) ); + } + target.setForCalendarConversion( zonedDateTimeToCalendar( source.getForCalendarConversion() ) ); + if ( source.getForDateConversionWithZonedDateTime() != null ) { + target.setForDateConversionWithZonedDateTime( Date.from( source.getForDateConversionWithZonedDateTime().toInstant() ) ); + } + if ( source.getForDateConversionWithLocalDateTime() != null ) { + target.setForDateConversionWithLocalDateTime( Date.from( source.getForDateConversionWithLocalDateTime().toInstant( ZoneOffset.UTC ) ) ); + } + if ( source.getForDateConversionWithLocalDate() != null ) { + target.setForDateConversionWithLocalDate( Date.from( source.getForDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant() ) ); + } + if ( source.getForSqlDateConversionWithLocalDate() != null ) { + target.setForSqlDateConversionWithLocalDate( new java.sql.Date( source.getForSqlDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant().toEpochMilli() ) ); + } + if ( source.getForDateConversionWithInstant() != null ) { + target.setForDateConversionWithInstant( Date.from( source.getForDateConversionWithInstant() ) ); + } + if ( source.getForInstantConversionWithString() != null ) { + target.setForInstantConversionWithString( source.getForInstantConversionWithString().toString() ); + } + if ( source.getForPeriodConversionWithString() != null ) { + target.setForPeriodConversionWithString( source.getForPeriodConversionWithString().toString() ); + } + if ( source.getForDurationConversionWithString() != null ) { + target.setForDurationConversionWithString( source.getForDurationConversionWithString().toString() ); + } + + return target; + } + + @Override + public Target sourceToTargetLocalDateTimeMapped(Source source) { + if ( source == null ) { + return null; + } + + Target target = new Target(); + + if ( source.getLocalDateTime() != null ) { + target.setLocalDateTime( dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242.format( source.getLocalDateTime() ) ); + } + if ( source.getZonedDateTime() != null ) { + target.setZonedDateTime( DateTimeFormatter.ISO_DATE_TIME.format( source.getZonedDateTime() ) ); + } + if ( source.getLocalDate() != null ) { + target.setLocalDate( DateTimeFormatter.ISO_LOCAL_DATE.format( source.getLocalDate() ) ); + } + if ( source.getLocalTime() != null ) { + target.setLocalTime( DateTimeFormatter.ISO_LOCAL_TIME.format( source.getLocalTime() ) ); + } + target.setForCalendarConversion( zonedDateTimeToCalendar( source.getForCalendarConversion() ) ); + if ( source.getForDateConversionWithZonedDateTime() != null ) { + target.setForDateConversionWithZonedDateTime( Date.from( source.getForDateConversionWithZonedDateTime().toInstant() ) ); + } + if ( source.getForDateConversionWithLocalDateTime() != null ) { + target.setForDateConversionWithLocalDateTime( Date.from( source.getForDateConversionWithLocalDateTime().toInstant( ZoneOffset.UTC ) ) ); + } + if ( source.getForDateConversionWithLocalDate() != null ) { + target.setForDateConversionWithLocalDate( Date.from( source.getForDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant() ) ); + } + if ( source.getForSqlDateConversionWithLocalDate() != null ) { + target.setForSqlDateConversionWithLocalDate( new java.sql.Date( source.getForSqlDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant().toEpochMilli() ) ); + } + if ( source.getForDateConversionWithInstant() != null ) { + target.setForDateConversionWithInstant( Date.from( source.getForDateConversionWithInstant() ) ); + } + if ( source.getForInstantConversionWithString() != null ) { + target.setForInstantConversionWithString( source.getForInstantConversionWithString().toString() ); + } + if ( source.getForPeriodConversionWithString() != null ) { + target.setForPeriodConversionWithString( source.getForPeriodConversionWithString().toString() ); + } + if ( source.getForDurationConversionWithString() != null ) { + target.setForDurationConversionWithString( source.getForDurationConversionWithString().toString() ); + } + + return target; + } + + @Override + public Target sourceToTargetLocalDateMapped(Source source) { + if ( source == null ) { + return null; + } + + Target target = new Target(); + + if ( source.getLocalDate() != null ) { + target.setLocalDate( dateTimeFormatter_dd_MM_yyyy_11900521056.format( source.getLocalDate() ) ); + } + if ( source.getZonedDateTime() != null ) { + target.setZonedDateTime( DateTimeFormatter.ISO_DATE_TIME.format( source.getZonedDateTime() ) ); + } + if ( source.getLocalDateTime() != null ) { + target.setLocalDateTime( DateTimeFormatter.ISO_LOCAL_DATE_TIME.format( source.getLocalDateTime() ) ); + } + if ( source.getLocalTime() != null ) { + target.setLocalTime( DateTimeFormatter.ISO_LOCAL_TIME.format( source.getLocalTime() ) ); + } + target.setForCalendarConversion( zonedDateTimeToCalendar( source.getForCalendarConversion() ) ); + if ( source.getForDateConversionWithZonedDateTime() != null ) { + target.setForDateConversionWithZonedDateTime( Date.from( source.getForDateConversionWithZonedDateTime().toInstant() ) ); + } + if ( source.getForDateConversionWithLocalDateTime() != null ) { + target.setForDateConversionWithLocalDateTime( Date.from( source.getForDateConversionWithLocalDateTime().toInstant( ZoneOffset.UTC ) ) ); + } + if ( source.getForDateConversionWithLocalDate() != null ) { + target.setForDateConversionWithLocalDate( Date.from( source.getForDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant() ) ); + } + if ( source.getForSqlDateConversionWithLocalDate() != null ) { + target.setForSqlDateConversionWithLocalDate( new java.sql.Date( source.getForSqlDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant().toEpochMilli() ) ); + } + if ( source.getForDateConversionWithInstant() != null ) { + target.setForDateConversionWithInstant( Date.from( source.getForDateConversionWithInstant() ) ); + } + if ( source.getForInstantConversionWithString() != null ) { + target.setForInstantConversionWithString( source.getForInstantConversionWithString().toString() ); + } + if ( source.getForPeriodConversionWithString() != null ) { + target.setForPeriodConversionWithString( source.getForPeriodConversionWithString().toString() ); + } + if ( source.getForDurationConversionWithString() != null ) { + target.setForDurationConversionWithString( source.getForDurationConversionWithString().toString() ); + } + + return target; + } + + @Override + public Target sourceToTargetLocalTimeMapped(Source source) { + if ( source == null ) { + return null; + } + + Target target = new Target(); + + if ( source.getLocalTime() != null ) { + target.setLocalTime( dateTimeFormatter_HH_mm_168697690.format( source.getLocalTime() ) ); + } + if ( source.getZonedDateTime() != null ) { + target.setZonedDateTime( DateTimeFormatter.ISO_DATE_TIME.format( source.getZonedDateTime() ) ); + } + if ( source.getLocalDateTime() != null ) { + target.setLocalDateTime( DateTimeFormatter.ISO_LOCAL_DATE_TIME.format( source.getLocalDateTime() ) ); + } + if ( source.getLocalDate() != null ) { + target.setLocalDate( DateTimeFormatter.ISO_LOCAL_DATE.format( source.getLocalDate() ) ); + } + target.setForCalendarConversion( zonedDateTimeToCalendar( source.getForCalendarConversion() ) ); + if ( source.getForDateConversionWithZonedDateTime() != null ) { + target.setForDateConversionWithZonedDateTime( Date.from( source.getForDateConversionWithZonedDateTime().toInstant() ) ); + } + if ( source.getForDateConversionWithLocalDateTime() != null ) { + target.setForDateConversionWithLocalDateTime( Date.from( source.getForDateConversionWithLocalDateTime().toInstant( ZoneOffset.UTC ) ) ); + } + if ( source.getForDateConversionWithLocalDate() != null ) { + target.setForDateConversionWithLocalDate( Date.from( source.getForDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant() ) ); + } + if ( source.getForSqlDateConversionWithLocalDate() != null ) { + target.setForSqlDateConversionWithLocalDate( new java.sql.Date( source.getForSqlDateConversionWithLocalDate().atStartOfDay( ZoneOffset.UTC ).toInstant().toEpochMilli() ) ); + } + if ( source.getForDateConversionWithInstant() != null ) { + target.setForDateConversionWithInstant( Date.from( source.getForDateConversionWithInstant() ) ); + } + if ( source.getForInstantConversionWithString() != null ) { + target.setForInstantConversionWithString( source.getForInstantConversionWithString().toString() ); + } + if ( source.getForPeriodConversionWithString() != null ) { + target.setForPeriodConversionWithString( source.getForPeriodConversionWithString().toString() ); + } + if ( source.getForDurationConversionWithString() != null ) { + target.setForDurationConversionWithString( source.getForDurationConversionWithString().toString() ); + } + + return target; + } + + @Override + public Source targetToSource(Target target) { + if ( target == null ) { + return null; + } + + Source source = new Source(); + + if ( target.getZonedDateTime() != null ) { + source.setZonedDateTime( ZonedDateTime.parse( target.getZonedDateTime(), dateTimeFormatter_dd_MM_yyyy_HH_mm_z_01894582668 ) ); + } + if ( target.getLocalDateTime() != null ) { + source.setLocalDateTime( LocalDateTime.parse( target.getLocalDateTime(), dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 ) ); + } + if ( target.getLocalDate() != null ) { + source.setLocalDate( LocalDate.parse( target.getLocalDate(), dateTimeFormatter_dd_MM_yyyy_11900521056 ) ); + } + if ( target.getLocalTime() != null ) { + source.setLocalTime( LocalTime.parse( target.getLocalTime(), dateTimeFormatter_HH_mm_168697690 ) ); + } + source.setForCalendarConversion( calendarToZonedDateTime( target.getForCalendarConversion() ) ); + if ( target.getForDateConversionWithZonedDateTime() != null ) { + source.setForDateConversionWithZonedDateTime( ZonedDateTime.ofInstant( target.getForDateConversionWithZonedDateTime().toInstant(), ZoneId.systemDefault() ) ); + } + if ( target.getForDateConversionWithLocalDateTime() != null ) { + source.setForDateConversionWithLocalDateTime( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDateTime().toInstant(), ZoneId.of( "UTC" ) ) ); + } + if ( target.getForDateConversionWithLocalDate() != null ) { + source.setForDateConversionWithLocalDate( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDate().toInstant(), ZoneOffset.UTC ).toLocalDate() ); + } + if ( target.getForSqlDateConversionWithLocalDate() != null ) { + source.setForSqlDateConversionWithLocalDate( target.getForSqlDateConversionWithLocalDate().toLocalDate() ); + } + if ( target.getForDateConversionWithInstant() != null ) { + source.setForDateConversionWithInstant( target.getForDateConversionWithInstant().toInstant() ); + } + if ( target.getForInstantConversionWithString() != null ) { + source.setForInstantConversionWithString( Instant.parse( target.getForInstantConversionWithString() ) ); + } + if ( target.getForPeriodConversionWithString() != null ) { + source.setForPeriodConversionWithString( Period.parse( target.getForPeriodConversionWithString() ) ); + } + if ( target.getForDurationConversionWithString() != null ) { + source.setForDurationConversionWithString( Duration.parse( target.getForDurationConversionWithString() ) ); + } + + return source; + } + + @Override + public Source targetToSourceDateTimeMapped(Target target) { + if ( target == null ) { + return null; + } + + Source source = new Source(); + + if ( target.getZonedDateTime() != null ) { + source.setZonedDateTime( ZonedDateTime.parse( target.getZonedDateTime(), dateTimeFormatter_dd_MM_yyyy_HH_mm_z_01894582668 ) ); + } + if ( target.getLocalDateTime() != null ) { + source.setLocalDateTime( LocalDateTime.parse( target.getLocalDateTime() ) ); + } + if ( target.getLocalDate() != null ) { + source.setLocalDate( LocalDate.parse( target.getLocalDate() ) ); + } + if ( target.getLocalTime() != null ) { + source.setLocalTime( LocalTime.parse( target.getLocalTime() ) ); + } + source.setForCalendarConversion( calendarToZonedDateTime( target.getForCalendarConversion() ) ); + if ( target.getForDateConversionWithZonedDateTime() != null ) { + source.setForDateConversionWithZonedDateTime( ZonedDateTime.ofInstant( target.getForDateConversionWithZonedDateTime().toInstant(), ZoneId.systemDefault() ) ); + } + if ( target.getForDateConversionWithLocalDateTime() != null ) { + source.setForDateConversionWithLocalDateTime( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDateTime().toInstant(), ZoneId.of( "UTC" ) ) ); + } + if ( target.getForDateConversionWithLocalDate() != null ) { + source.setForDateConversionWithLocalDate( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDate().toInstant(), ZoneOffset.UTC ).toLocalDate() ); + } + if ( target.getForSqlDateConversionWithLocalDate() != null ) { + source.setForSqlDateConversionWithLocalDate( target.getForSqlDateConversionWithLocalDate().toLocalDate() ); + } + if ( target.getForDateConversionWithInstant() != null ) { + source.setForDateConversionWithInstant( target.getForDateConversionWithInstant().toInstant() ); + } + if ( target.getForInstantConversionWithString() != null ) { + source.setForInstantConversionWithString( Instant.parse( target.getForInstantConversionWithString() ) ); + } + if ( target.getForPeriodConversionWithString() != null ) { + source.setForPeriodConversionWithString( Period.parse( target.getForPeriodConversionWithString() ) ); + } + if ( target.getForDurationConversionWithString() != null ) { + source.setForDurationConversionWithString( Duration.parse( target.getForDurationConversionWithString() ) ); + } + + return source; + } + + @Override + public Source targetToSourceLocalDateTimeMapped(Target target) { + if ( target == null ) { + return null; + } + + Source source = new Source(); + + if ( target.getLocalDateTime() != null ) { + source.setLocalDateTime( LocalDateTime.parse( target.getLocalDateTime(), dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 ) ); + } + if ( target.getZonedDateTime() != null ) { + source.setZonedDateTime( ZonedDateTime.parse( target.getZonedDateTime() ) ); + } + if ( target.getLocalDate() != null ) { + source.setLocalDate( LocalDate.parse( target.getLocalDate() ) ); + } + if ( target.getLocalTime() != null ) { + source.setLocalTime( LocalTime.parse( target.getLocalTime() ) ); + } + source.setForCalendarConversion( calendarToZonedDateTime( target.getForCalendarConversion() ) ); + if ( target.getForDateConversionWithZonedDateTime() != null ) { + source.setForDateConversionWithZonedDateTime( ZonedDateTime.ofInstant( target.getForDateConversionWithZonedDateTime().toInstant(), ZoneId.systemDefault() ) ); + } + if ( target.getForDateConversionWithLocalDateTime() != null ) { + source.setForDateConversionWithLocalDateTime( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDateTime().toInstant(), ZoneId.of( "UTC" ) ) ); + } + if ( target.getForDateConversionWithLocalDate() != null ) { + source.setForDateConversionWithLocalDate( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDate().toInstant(), ZoneOffset.UTC ).toLocalDate() ); + } + if ( target.getForSqlDateConversionWithLocalDate() != null ) { + source.setForSqlDateConversionWithLocalDate( target.getForSqlDateConversionWithLocalDate().toLocalDate() ); + } + if ( target.getForDateConversionWithInstant() != null ) { + source.setForDateConversionWithInstant( target.getForDateConversionWithInstant().toInstant() ); + } + if ( target.getForInstantConversionWithString() != null ) { + source.setForInstantConversionWithString( Instant.parse( target.getForInstantConversionWithString() ) ); + } + if ( target.getForPeriodConversionWithString() != null ) { + source.setForPeriodConversionWithString( Period.parse( target.getForPeriodConversionWithString() ) ); + } + if ( target.getForDurationConversionWithString() != null ) { + source.setForDurationConversionWithString( Duration.parse( target.getForDurationConversionWithString() ) ); + } + + return source; + } + + @Override + public Source targetToSourceLocalDateMapped(Target target) { + if ( target == null ) { + return null; + } + + Source source = new Source(); + + if ( target.getLocalDate() != null ) { + source.setLocalDate( LocalDate.parse( target.getLocalDate(), dateTimeFormatter_dd_MM_yyyy_11900521056 ) ); + } + if ( target.getZonedDateTime() != null ) { + source.setZonedDateTime( ZonedDateTime.parse( target.getZonedDateTime() ) ); + } + if ( target.getLocalDateTime() != null ) { + source.setLocalDateTime( LocalDateTime.parse( target.getLocalDateTime() ) ); + } + if ( target.getLocalTime() != null ) { + source.setLocalTime( LocalTime.parse( target.getLocalTime() ) ); + } + source.setForCalendarConversion( calendarToZonedDateTime( target.getForCalendarConversion() ) ); + if ( target.getForDateConversionWithZonedDateTime() != null ) { + source.setForDateConversionWithZonedDateTime( ZonedDateTime.ofInstant( target.getForDateConversionWithZonedDateTime().toInstant(), ZoneId.systemDefault() ) ); + } + if ( target.getForDateConversionWithLocalDateTime() != null ) { + source.setForDateConversionWithLocalDateTime( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDateTime().toInstant(), ZoneId.of( "UTC" ) ) ); + } + if ( target.getForDateConversionWithLocalDate() != null ) { + source.setForDateConversionWithLocalDate( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDate().toInstant(), ZoneOffset.UTC ).toLocalDate() ); + } + if ( target.getForSqlDateConversionWithLocalDate() != null ) { + source.setForSqlDateConversionWithLocalDate( target.getForSqlDateConversionWithLocalDate().toLocalDate() ); + } + if ( target.getForDateConversionWithInstant() != null ) { + source.setForDateConversionWithInstant( target.getForDateConversionWithInstant().toInstant() ); + } + if ( target.getForInstantConversionWithString() != null ) { + source.setForInstantConversionWithString( Instant.parse( target.getForInstantConversionWithString() ) ); + } + if ( target.getForPeriodConversionWithString() != null ) { + source.setForPeriodConversionWithString( Period.parse( target.getForPeriodConversionWithString() ) ); + } + if ( target.getForDurationConversionWithString() != null ) { + source.setForDurationConversionWithString( Duration.parse( target.getForDurationConversionWithString() ) ); + } + + return source; + } + + @Override + public Source targetToSourceLocalTimeMapped(Target target) { + if ( target == null ) { + return null; + } + + Source source = new Source(); + + if ( target.getLocalTime() != null ) { + source.setLocalTime( LocalTime.parse( target.getLocalTime(), dateTimeFormatter_HH_mm_168697690 ) ); + } + if ( target.getZonedDateTime() != null ) { + source.setZonedDateTime( ZonedDateTime.parse( target.getZonedDateTime() ) ); + } + if ( target.getLocalDateTime() != null ) { + source.setLocalDateTime( LocalDateTime.parse( target.getLocalDateTime() ) ); + } + if ( target.getLocalDate() != null ) { + source.setLocalDate( LocalDate.parse( target.getLocalDate() ) ); + } + source.setForCalendarConversion( calendarToZonedDateTime( target.getForCalendarConversion() ) ); + if ( target.getForDateConversionWithZonedDateTime() != null ) { + source.setForDateConversionWithZonedDateTime( ZonedDateTime.ofInstant( target.getForDateConversionWithZonedDateTime().toInstant(), ZoneId.systemDefault() ) ); + } + if ( target.getForDateConversionWithLocalDateTime() != null ) { + source.setForDateConversionWithLocalDateTime( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDateTime().toInstant(), ZoneId.of( "UTC" ) ) ); + } + if ( target.getForDateConversionWithLocalDate() != null ) { + source.setForDateConversionWithLocalDate( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDate().toInstant(), ZoneOffset.UTC ).toLocalDate() ); + } + if ( target.getForSqlDateConversionWithLocalDate() != null ) { + source.setForSqlDateConversionWithLocalDate( target.getForSqlDateConversionWithLocalDate().toLocalDate() ); + } + if ( target.getForDateConversionWithInstant() != null ) { + source.setForDateConversionWithInstant( target.getForDateConversionWithInstant().toInstant() ); + } + if ( target.getForInstantConversionWithString() != null ) { + source.setForInstantConversionWithString( Instant.parse( target.getForInstantConversionWithString() ) ); + } + if ( target.getForPeriodConversionWithString() != null ) { + source.setForPeriodConversionWithString( Period.parse( target.getForPeriodConversionWithString() ) ); + } + if ( target.getForDurationConversionWithString() != null ) { + source.setForDurationConversionWithString( Duration.parse( target.getForDurationConversionWithString() ) ); + } + + return source; + } + + @Override + public Source targetToSourceDefaultMapping(Target target) { + if ( target == null ) { + return null; + } + + Source source = new Source(); + + if ( target.getZonedDateTime() != null ) { + source.setZonedDateTime( ZonedDateTime.parse( target.getZonedDateTime(), dateTimeFormatter_dd_MM_yyyy_HH_mm_z_01894582668 ) ); + } + if ( target.getLocalDateTime() != null ) { + source.setLocalDateTime( LocalDateTime.parse( target.getLocalDateTime(), dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 ) ); + } + if ( target.getLocalDate() != null ) { + source.setLocalDate( LocalDate.parse( target.getLocalDate(), dateTimeFormatter_dd_MM_yyyy_11900521056 ) ); + } + if ( target.getLocalTime() != null ) { + source.setLocalTime( LocalTime.parse( target.getLocalTime(), dateTimeFormatter_HH_mm_168697690 ) ); + } + source.setForCalendarConversion( calendarToZonedDateTime( target.getForCalendarConversion() ) ); + if ( target.getForDateConversionWithZonedDateTime() != null ) { + source.setForDateConversionWithZonedDateTime( ZonedDateTime.ofInstant( target.getForDateConversionWithZonedDateTime().toInstant(), ZoneId.systemDefault() ) ); + } + if ( target.getForDateConversionWithLocalDateTime() != null ) { + source.setForDateConversionWithLocalDateTime( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDateTime().toInstant(), ZoneId.of( "UTC" ) ) ); + } + if ( target.getForDateConversionWithLocalDate() != null ) { + source.setForDateConversionWithLocalDate( LocalDateTime.ofInstant( target.getForDateConversionWithLocalDate().toInstant(), ZoneOffset.UTC ).toLocalDate() ); + } + if ( target.getForSqlDateConversionWithLocalDate() != null ) { + source.setForSqlDateConversionWithLocalDate( target.getForSqlDateConversionWithLocalDate().toLocalDate() ); + } + if ( target.getForDateConversionWithInstant() != null ) { + source.setForDateConversionWithInstant( target.getForDateConversionWithInstant().toInstant() ); + } + if ( target.getForInstantConversionWithString() != null ) { + source.setForInstantConversionWithString( Instant.parse( target.getForInstantConversionWithString() ) ); + } + if ( target.getForPeriodConversionWithString() != null ) { + source.setForPeriodConversionWithString( Period.parse( target.getForPeriodConversionWithString() ) ); + } + if ( target.getForDurationConversionWithString() != null ) { + source.setForDurationConversionWithString( Duration.parse( target.getForDurationConversionWithString() ) ); + } + + return source; + } + + private ZonedDateTime calendarToZonedDateTime(Calendar cal) { + if ( cal == null ) { + return null; + } + + return ZonedDateTime.ofInstant( cal.toInstant(), cal.getTimeZone().toZoneId() ); + } + + private Calendar zonedDateTimeToCalendar(ZonedDateTime dateTime) { + if ( dateTime == null ) { + return null; + } + + Calendar instance = Calendar.getInstance( TimeZone.getTimeZone( dateTime.getZone() ) ); + instance.setTimeInMillis( dateTime.toInstant().toEpochMilli() ); + return instance; + } +} diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/SourceTargetMapperImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/SourceTargetMapperImpl.java new file mode 100644 index 000000000..98c2c19bb --- /dev/null +++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/SourceTargetMapperImpl.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.conversion.java8time.custompatterndatetimeformattergenerated; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import javax.annotation.Generated; + +@Generated( + value = "org.mapstruct.ap.MappingProcessor", + date = "2021-05-16T13:11:04+0200", + comments = "version: , compiler: javac, environment: Java 1.8.0_275 (AdoptOpenJDK)" +) +public class SourceTargetMapperImpl implements SourceTargetMapper { + + private final DateTimeFormatter dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 = DateTimeFormatter.ofPattern( "dd.MM.yyyy HH:mm" ); + private final DateTimeFormatter dateTimeFormatter_dd_MM_yyyy_HH_mm_12071757710 = DateTimeFormatter.ofPattern( "dd.MM.yyyy HH.mm" ); + + @Override + public Target map(Source source) { + if ( source == null ) { + return null; + } + + Target target = new Target(); + + if ( source.getLocalDateTime1() != null ) { + target.setLocalDateTime1( dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242.format( source.getLocalDateTime1() ) ); + } + if ( source.getLocalDateTime2() != null ) { + target.setLocalDateTime2( dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242.format( source.getLocalDateTime2() ) ); + } + if ( source.getLocalDateTime3() != null ) { + target.setLocalDateTime3( dateTimeFormatter_dd_MM_yyyy_HH_mm_12071757710.format( source.getLocalDateTime3() ) ); + } + + return target; + } + + @Override + public Source map(Target target) { + if ( target == null ) { + return null; + } + + Source source = new Source(); + + if ( target.getLocalDateTime1() != null ) { + source.setLocalDateTime1( LocalDateTime.parse( target.getLocalDateTime1(), dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 ) ); + } + if ( target.getLocalDateTime2() != null ) { + source.setLocalDateTime2( LocalDateTime.parse( target.getLocalDateTime2(), dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 ) ); + } + if ( target.getLocalDateTime3() != null ) { + source.setLocalDateTime3( LocalDateTime.parse( target.getLocalDateTime3(), dateTimeFormatter_dd_MM_yyyy_HH_mm_12071757710 ) ); + } + + return source; + } +}