#1523 dont lose timezone mapping Calendar to XMLGregorianCalendar

This commit is contained in:
Christian Bandowski 2018-06-15 22:26:15 +02:00 committed by sjaakd
parent f4ed077aeb
commit 508de6733e
8 changed files with 310 additions and 1 deletions

View File

@ -55,6 +55,7 @@ public class BuiltInMappingMethods {
if ( isJava8TimeAvailable( typeFactory ) ) {
builtInMethods.add( new ZonedDateTimeToCalendar( typeFactory ) );
builtInMethods.add( new ZonedDateTimeToXmlGregorianCalendar( typeFactory ) );
builtInMethods.add( new CalendarToZonedDateTime( typeFactory ) );
if ( isXmlGregorianCalendarPresent ) {
builtInMethods.add( new XmlGregorianCalendarToLocalDate( typeFactory ) );

View File

@ -0,0 +1,70 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.ap.internal.model.source.builtin;
import java.time.ZonedDateTime;
import java.util.GregorianCalendar;
import java.util.Set;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory;
import static org.mapstruct.ap.internal.util.Collections.asSet;
/**
* @author Christian Bandowski
*/
public class ZonedDateTimeToXmlGregorianCalendar extends BuiltInMethod {
private final Parameter parameter;
private final Type returnType;
private final Set<Type> importTypes;
public ZonedDateTimeToXmlGregorianCalendar(TypeFactory typeFactory) {
this.parameter = new Parameter( "zdt ", typeFactory.getType( ZonedDateTime.class ) );
this.returnType = typeFactory.getType( XMLGregorianCalendar.class );
this.importTypes = asSet(
returnType,
parameter.getType(),
typeFactory.getType( DatatypeFactory.class ),
typeFactory.getType( GregorianCalendar.class ),
typeFactory.getType( DatatypeConfigurationException.class )
);
}
@Override
public Set<Type> getImportTypes() {
return importTypes;
}
@Override
public Parameter getParameter() {
return parameter;
}
@Override
public Type getReturnType() {
return returnType;
}
}

View File

@ -25,7 +25,7 @@ private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@incl
}
try {
<@includeModel object=findType("GregorianCalendar")/> gcal = new <@includeModel object=findType("GregorianCalendar")/>();
<@includeModel object=findType("GregorianCalendar")/> gcal = new <@includeModel object=findType("GregorianCalendar")/>( cal.getTimeZone() );
gcal.setTimeInMillis( cal.getTimeInMillis() );
return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( gcal );
}

View File

@ -0,0 +1,33 @@
<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" -->
<#--
Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
and/or other contributors as indicated by the @authors tag. See the
copyright.txt file in the distribution for a full listing of all
contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("ZonedDateTime")/> zdt ) {
if ( zdt == null ) {
return null;
}
try {
return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( <@includeModel object=findType("GregorianCalendar")/>.from( zdt ) );
}
catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) {
throw new RuntimeException( ex );
}
}

View File

@ -0,0 +1,34 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.ap.test.bugs._1523.java8;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author Christian Bandowski
*/
@Mapper
public abstract class Issue1523Mapper {
public static final Issue1523Mapper INSTANCE = Mappers.getMapper( Issue1523Mapper.class );
public abstract Target map(Source source);
}

View File

@ -0,0 +1,86 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.ap.test.bugs._1523.java8;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.TimeZone;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* This test will evaluate if the conversion from {@code Calendar} to {@code XMLGregorianCalendar} works in case the
* default timezone was not used. Additionally a direct conversion between {@code ZonedDateTime} to
* {@code XMLGregorianCalendar} was added for this issue to improve readability / performance. This will be tested as
* well.
*
* @author Christian Bandowski
*/
@WithClasses({
Issue1523Mapper.class,
Source.class,
Target.class
})
@RunWith(AnnotationProcessorTestRunner.class)
@IssueKey("1523")
public class Issue1523Test {
private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault();
@BeforeClass
public static void before() {
// we want to test that the timezone will correctly be used in mapped XMLGregorianCalendar and not the
// default one, so we must ensure that we use a different timezone than the default one -> set the default
// one explicitly to UTC
TimeZone.setDefault( TimeZone.getTimeZone( "UTC" ) );
}
@AfterClass
public static void after() {
// revert the changed default TZ
TimeZone.setDefault( DEFAULT_TIMEZONE );
}
@Test
public void testThatCorrectTimeZoneWillBeUsedInTarget() {
Source source = new Source();
// default one was explicitly set to UTC, thus +01:00 is a different one
source.setValue( ZonedDateTime.parse( "2018-06-15T00:00:00+01:00" ) );
Calendar cal = Calendar.getInstance( TimeZone.getTimeZone( "GMT+01:00" ) );
cal.set( 2018, 02, 15, 00, 00, 00 );
source.setValue2( cal );
Target target = Issue1523Mapper.INSTANCE.map( source );
assertThat( target ).isNotNull();
assertThat( target.getValue() ).isNotNull();
assertThat( target.getValue2() ).isNotNull();
// +01:00 -> offset is 60 min
assertThat( target.getValue().getTimezone() ).isEqualTo( 60 );
assertThat( target.getValue2().getTimezone() ).isEqualTo( 60 );
}
}

View File

@ -0,0 +1,43 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.ap.test.bugs._1523.java8;
import java.time.ZonedDateTime;
import java.util.Calendar;
public class Source {
private ZonedDateTime value;
private Calendar value2;
public ZonedDateTime getValue() {
return value;
}
public void setValue(ZonedDateTime value) {
this.value = value;
}
public Calendar getValue2() {
return value2;
}
public void setValue2(Calendar value2) {
this.value2 = value2;
}
}

View File

@ -0,0 +1,42 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.ap.test.bugs._1523.java8;
import javax.xml.datatype.XMLGregorianCalendar;
public class Target {
private XMLGregorianCalendar value;
private XMLGregorianCalendar value2;
public XMLGregorianCalendar getValue() {
return value;
}
public void setValue(XMLGregorianCalendar value) {
this.value = value;
}
public XMLGregorianCalendar getValue2() {
return value2;
}
public void setValue2(XMLGregorianCalendar value2) {
this.value2 = value2;
}
}