#1576 Delay determining whether a Type needs to be imported & java.time cleanup (#1642)

This commit is contained in:
Sjaak Derksen 2018-11-06 07:36:09 +00:00 committed by GitHub
parent 3ff4ebd60a
commit cf668bea77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 417 additions and 230 deletions

View File

@ -613,7 +613,7 @@
<configuration> <configuration>
<signature> <signature>
<groupId>org.codehaus.mojo.signature</groupId> <groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java16</artifactId> <artifactId>java18</artifactId>
<version>1.0</version> <version>1.0</version>
</signature> </signature>
</configuration> </configuration>

View File

@ -13,9 +13,10 @@ import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor; import javax.annotation.processing.Processor;
@ -25,6 +26,7 @@ import javax.annotation.processing.SupportedOptions;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementKindVisitor6; import javax.lang.model.util.ElementKindVisitor6;
import javax.tools.Diagnostic.Kind; import javax.tools.Diagnostic.Kind;
@ -41,6 +43,8 @@ import org.mapstruct.ap.internal.util.AnnotationProcessorContext;
import org.mapstruct.ap.internal.util.RoundContext; import org.mapstruct.ap.internal.util.RoundContext;
import org.mapstruct.ap.spi.TypeHierarchyErroneousException; import org.mapstruct.ap.spi.TypeHierarchyErroneousException;
import static javax.lang.model.element.ElementKind.CLASS;
/** /**
* A JSR 269 annotation {@link Processor} which generates the implementations for mapper interfaces (interfaces * A JSR 269 annotation {@link Processor} which generates the implementations for mapper interfaces (interfaces
* annotated with {@code @Mapper}). * annotated with {@code @Mapper}).
@ -209,8 +213,9 @@ public class MappingProcessor extends AbstractProcessor {
// note that this assumes that a new source file is created for each mapper which must not // note that this assumes that a new source file is created for each mapper which must not
// necessarily be the case, e.g. in case of several mapper interfaces declared as inner types // necessarily be the case, e.g. in case of several mapper interfaces declared as inner types
// of one outer interface // of one outer interface
List<? extends Element> tst = mapperElement.getEnclosedElements();
ProcessorContext context = new DefaultModelElementProcessorContext( ProcessorContext context = new DefaultModelElementProcessorContext(
processingEnv, options, roundContext processingEnv, options, roundContext, getDeclaredTypesNotToBeImported( mapperElement )
); );
processMapperTypeElement( context, mapperElement ); processMapperTypeElement( context, mapperElement );
@ -225,6 +230,14 @@ public class MappingProcessor extends AbstractProcessor {
} }
} }
private Map<String, String> getDeclaredTypesNotToBeImported(TypeElement element) {
return element.getEnclosedElements().stream()
.filter( e -> CLASS.equals( e.getKind() ) )
.map( Element::getSimpleName )
.map( Name::toString )
.collect( Collectors.toMap( k -> k, v -> element.getQualifiedName().toString() + "." + v ) );
}
private void handleUncaughtError(Element element, Throwable thrown) { private void handleUncaughtError(Element element, Throwable thrown) {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
thrown.printStackTrace( new PrintWriter( sw ) ); thrown.printStackTrace( new PrintWriter( sw ) );

View File

@ -5,12 +5,12 @@
*/ */
package org.mapstruct.ap.internal.conversion; package org.mapstruct.ap.internal.conversion;
import java.time.format.DateTimeFormatter;
import java.util.Set; import java.util.Set;
import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.ConversionContext;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.util.Collections; import org.mapstruct.ap.internal.util.Collections;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import org.mapstruct.ap.internal.util.Strings; import org.mapstruct.ap.internal.util.Strings;
/** /**
@ -53,7 +53,7 @@ public abstract class AbstractJavaTimeToStringConversion extends SimpleConversio
@Override @Override
protected String getFromExpression(ConversionContext conversionContext) { protected String getFromExpression(ConversionContext conversionContext) {
// See http://docs.oracle.com/javase/tutorial/datetime/iso/format.html for how to parse Dates // See http://docs.oracle.com/javase/tutorial/datetime/iso/format.html for how to parse Dates
return new StringBuilder().append( conversionContext.getTargetType().getReferenceName() ) return new StringBuilder().append( conversionContext.getTargetType().createReferenceName() )
.append( ".parse( " ) .append( ".parse( " )
.append( parametersListForParsing( conversionContext ) ) .append( parametersListForParsing( conversionContext ) )
.append( " )" ).toString(); .append( " )" ).toString();
@ -72,7 +72,7 @@ public abstract class AbstractJavaTimeToStringConversion extends SimpleConversio
@Override @Override
protected Set<Type> getToConversionImportTypes(ConversionContext conversionContext) { protected Set<Type> getToConversionImportTypes(ConversionContext conversionContext) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTypeFactory().getType( JavaTimeConstants.DATE_TIME_FORMATTER_FQN ) conversionContext.getTypeFactory().getType( DateTimeFormatter.class )
); );
} }
@ -81,7 +81,7 @@ public abstract class AbstractJavaTimeToStringConversion extends SimpleConversio
if ( !Strings.isEmpty( conversionContext.getDateFormat() ) ) { if ( !Strings.isEmpty( conversionContext.getDateFormat() ) ) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTargetType(), conversionContext.getTargetType(),
conversionContext.getTypeFactory().getType( JavaTimeConstants.DATE_TIME_FORMATTER_FQN ) conversionContext.getTypeFactory().getType( DateTimeFormatter.class )
); );
} }

View File

@ -11,11 +11,15 @@ import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Currency; import java.util.Currency;
import java.util.Locale; import java.util.Locale;
import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.ConversionContext;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import org.mapstruct.ap.internal.util.JodaTimeConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants;
/** /**
@ -37,7 +41,7 @@ public final class ConversionUtils {
* @return Name or fully-qualified name. * @return Name or fully-qualified name.
*/ */
private static String typeReferenceName(ConversionContext conversionContext, String canonicalName) { private static String typeReferenceName(ConversionContext conversionContext, String canonicalName) {
return conversionContext.getTypeFactory().getType( canonicalName ).getReferenceName(); return conversionContext.getTypeFactory().getType( canonicalName ).createReferenceName();
} }
/** /**
@ -49,7 +53,7 @@ public final class ConversionUtils {
* @return Name or fully-qualified name. * @return Name or fully-qualified name.
*/ */
private static String typeReferenceName(ConversionContext conversionContext, Class<?> type) { private static String typeReferenceName(ConversionContext conversionContext, Class<?> type) {
return conversionContext.getTypeFactory().getType( type ).getReferenceName(); return conversionContext.getTypeFactory().getType( type ).createReferenceName();
} }
/** /**
@ -170,7 +174,7 @@ public final class ConversionUtils {
* @return Name or fully-qualified name. * @return Name or fully-qualified name.
*/ */
public static String zoneOffset(ConversionContext conversionContext) { public static String zoneOffset(ConversionContext conversionContext) {
return typeReferenceName( conversionContext, JavaTimeConstants.ZONE_OFFSET_FQN ); return typeReferenceName( conversionContext, ZoneOffset.class );
} }
/** /**
@ -181,7 +185,7 @@ public final class ConversionUtils {
* @return Name or fully-qualified name. * @return Name or fully-qualified name.
*/ */
public static String zoneId(ConversionContext conversionContext) { public static String zoneId(ConversionContext conversionContext) {
return typeReferenceName( conversionContext, JavaTimeConstants.ZONE_ID_FQN ); return typeReferenceName( conversionContext, ZoneId.class );
} }
/** /**
@ -192,7 +196,7 @@ public final class ConversionUtils {
* @return Name or fully-qualified name. * @return Name or fully-qualified name.
*/ */
public static String localDateTime(ConversionContext conversionContext) { public static String localDateTime(ConversionContext conversionContext) {
return typeReferenceName( conversionContext, JavaTimeConstants.LOCAL_DATE_TIME_FQN ); return typeReferenceName( conversionContext, LocalDateTime.class );
} }
/** /**
@ -203,7 +207,7 @@ public final class ConversionUtils {
* @return Name or fully-qualified name. * @return Name or fully-qualified name.
*/ */
public static String zonedDateTime(ConversionContext conversionContext) { public static String zonedDateTime(ConversionContext conversionContext) {
return typeReferenceName( conversionContext, JavaTimeConstants.ZONED_DATE_TIME_FQN ); return typeReferenceName( conversionContext, ZonedDateTime.class );
} }
/** /**
@ -214,7 +218,7 @@ public final class ConversionUtils {
* @return Name or fully-qualified name. * @return Name or fully-qualified name.
*/ */
public static String dateTimeFormatter(ConversionContext conversionContext) { public static String dateTimeFormatter(ConversionContext conversionContext) {
return typeReferenceName( conversionContext, JavaTimeConstants.DATE_TIME_FORMATTER_FQN ); return typeReferenceName( conversionContext, DateTimeFormatter.class );
} }
/** /**

View File

@ -9,6 +9,11 @@ import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.sql.Time; import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.Calendar; import java.util.Calendar;
import java.util.Currency; import java.util.Currency;
import java.util.Date; import java.util.Date;
@ -18,7 +23,6 @@ import javax.lang.model.util.Elements;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.common.TypeFactory;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import org.mapstruct.ap.internal.util.JodaTimeConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants;
import static org.mapstruct.ap.internal.conversion.ReverseConversion.reverse; import static org.mapstruct.ap.internal.conversion.ReverseConversion.reverse;
@ -207,22 +211,19 @@ public class Conversions {
} }
private void registerJava8TimeConversions() { private void registerJava8TimeConversions() {
if ( !isJava8TimeAvailable() ) {
return;
}
// Java 8 time to String // Java 8 time to String
register( JavaTimeConstants.ZONED_DATE_TIME_FQN, String.class, new JavaZonedDateTimeToStringConversion() ); register( ZonedDateTime.class, String.class, new JavaZonedDateTimeToStringConversion() );
register( JavaTimeConstants.LOCAL_DATE_FQN, String.class, new JavaLocalDateToStringConversion() ); register( LocalDate.class, String.class, new JavaLocalDateToStringConversion() );
register( JavaTimeConstants.LOCAL_DATE_TIME_FQN, String.class, new JavaLocalDateTimeToStringConversion() ); register( LocalDateTime.class, String.class, new JavaLocalDateTimeToStringConversion() );
register( JavaTimeConstants.LOCAL_TIME_FQN, String.class, new JavaLocalTimeToStringConversion() ); register( LocalTime.class, String.class, new JavaLocalTimeToStringConversion() );
// Java 8 to Date // Java 8 to Date
register( JavaTimeConstants.ZONED_DATE_TIME_FQN, Date.class, new JavaZonedDateTimeToDateConversion() ); register( ZonedDateTime.class, Date.class, new JavaZonedDateTimeToDateConversion() );
register( JavaTimeConstants.LOCAL_DATE_TIME_FQN, Date.class, new JavaLocalDateTimeToDateConversion() ); register( LocalDateTime.class, Date.class, new JavaLocalDateTimeToDateConversion() );
register( JavaTimeConstants.LOCAL_DATE_FQN, Date.class, new JavaLocalDateToDateConversion() ); register( LocalDate.class, Date.class, new JavaLocalDateToDateConversion() );
register( JavaTimeConstants.LOCAL_DATE_FQN, java.sql.Date.class, new JavaLocalDateToSqlDateConversion() ); register( LocalDate.class, java.sql.Date.class, new JavaLocalDateToSqlDateConversion() );
register( JavaTimeConstants.INSTANT, Date.class, new JavaInstantToDateConversion() ); register( Instant.class, Date.class, new JavaInstantToDateConversion() );
} }
@ -230,10 +231,6 @@ public class Conversions {
return typeFactory.isTypeAvailable( JodaTimeConstants.DATE_TIME_FQN ); return typeFactory.isTypeAvailable( JodaTimeConstants.DATE_TIME_FQN );
} }
private boolean isJava8TimeAvailable() {
return typeFactory.isTypeAvailable( JavaTimeConstants.ZONED_DATE_TIME_FQN );
}
private void registerNativeTypeConversion(Class<?> sourceType, Class<?> targetType) { private void registerNativeTypeConversion(Class<?> sourceType, Class<?> targetType) {
if ( sourceType.isPrimitive() && targetType.isPrimitive() ) { if ( sourceType.isPrimitive() && targetType.isPrimitive() ) {
register( sourceType, targetType, new PrimitiveToPrimitiveConversion( sourceType ) ); register( sourceType, targetType, new PrimitiveToPrimitiveConversion( sourceType ) );

View File

@ -26,7 +26,7 @@ public class EnumStringConversion extends SimpleConversion {
@Override @Override
public String getFromExpression(ConversionContext conversionContext) { public String getFromExpression(ConversionContext conversionContext) {
return "Enum.valueOf( " + conversionContext.getTargetType().getReferenceName() return "Enum.valueOf( " + conversionContext.getTargetType().createReferenceName()
+ ".class, <SOURCE> )"; + ".class, <SOURCE> )";
} }

View File

@ -5,6 +5,9 @@
*/ */
package org.mapstruct.ap.internal.conversion; package org.mapstruct.ap.internal.conversion;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
@ -16,9 +19,6 @@ import static org.mapstruct.ap.internal.conversion.ConversionUtils.date;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.localDateTime; import static org.mapstruct.ap.internal.conversion.ConversionUtils.localDateTime;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneId; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneId;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset;
import static org.mapstruct.ap.internal.util.JavaTimeConstants.LOCAL_DATE_TIME_FQN;
import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_ID_FQN;
import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_OFFSET_FQN;
/** /**
* SimpleConversion for mapping {@link java.time.LocalDateTime} to * SimpleConversion for mapping {@link java.time.LocalDateTime} to
@ -38,7 +38,7 @@ public class JavaLocalDateTimeToDateConversion extends SimpleConversion {
protected Set<Type> getToConversionImportTypes(ConversionContext conversionContext) { protected Set<Type> getToConversionImportTypes(ConversionContext conversionContext) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTypeFactory().getType( Date.class ), conversionContext.getTypeFactory().getType( Date.class ),
conversionContext.getTypeFactory().getType( ZONE_OFFSET_FQN ) conversionContext.getTypeFactory().getType( ZoneOffset.class )
); );
} }
@ -53,8 +53,8 @@ public class JavaLocalDateTimeToDateConversion extends SimpleConversion {
@Override @Override
protected Set<Type> getFromConversionImportTypes(ConversionContext conversionContext) { protected Set<Type> getFromConversionImportTypes(ConversionContext conversionContext) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTypeFactory().getType( LOCAL_DATE_TIME_FQN ), conversionContext.getTypeFactory().getType( LocalDateTime.class ),
conversionContext.getTypeFactory().getType( ZONE_ID_FQN ) conversionContext.getTypeFactory().getType( ZoneId.class )
); );
} }
} }

View File

@ -5,6 +5,8 @@
*/ */
package org.mapstruct.ap.internal.conversion; package org.mapstruct.ap.internal.conversion;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
@ -15,8 +17,6 @@ import org.mapstruct.ap.internal.util.Collections;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.date; import static org.mapstruct.ap.internal.conversion.ConversionUtils.date;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.localDateTime; import static org.mapstruct.ap.internal.conversion.ConversionUtils.localDateTime;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset;
import static org.mapstruct.ap.internal.util.JavaTimeConstants.LOCAL_DATE_TIME_FQN;
import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_OFFSET_FQN;
/** /**
* SimpleConversion for mapping {@link java.time.LocalDate} to * SimpleConversion for mapping {@link java.time.LocalDate} to
@ -36,7 +36,7 @@ public class JavaLocalDateToDateConversion extends SimpleConversion {
protected Set<Type> getToConversionImportTypes(ConversionContext conversionContext) { protected Set<Type> getToConversionImportTypes(ConversionContext conversionContext) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTypeFactory().getType( Date.class ), conversionContext.getTypeFactory().getType( Date.class ),
conversionContext.getTypeFactory().getType( ZONE_OFFSET_FQN ) conversionContext.getTypeFactory().getType( ZoneOffset.class )
); );
} }
@ -51,8 +51,8 @@ public class JavaLocalDateToDateConversion extends SimpleConversion {
@Override @Override
protected Set<Type> getFromConversionImportTypes(ConversionContext conversionContext) { protected Set<Type> getFromConversionImportTypes(ConversionContext conversionContext) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTypeFactory().getType( LOCAL_DATE_TIME_FQN ), conversionContext.getTypeFactory().getType( LocalDateTime.class ),
conversionContext.getTypeFactory().getType( ZONE_OFFSET_FQN ) conversionContext.getTypeFactory().getType( ZoneOffset.class )
); );
} }
} }

View File

@ -6,6 +6,7 @@
package org.mapstruct.ap.internal.conversion; package org.mapstruct.ap.internal.conversion;
import java.sql.Date; import java.sql.Date;
import java.time.ZoneOffset;
import java.util.Set; import java.util.Set;
import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.ConversionContext;
@ -14,7 +15,6 @@ import org.mapstruct.ap.internal.util.Collections;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.sqlDate; import static org.mapstruct.ap.internal.conversion.ConversionUtils.sqlDate;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset;
import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_OFFSET_FQN;
/** /**
* SimpleConversion for mapping {@link java.time.LocalDate} to * SimpleConversion for mapping {@link java.time.LocalDate} to
@ -34,7 +34,7 @@ public class JavaLocalDateToSqlDateConversion extends SimpleConversion {
protected Set<Type> getToConversionImportTypes(ConversionContext conversionContext) { protected Set<Type> getToConversionImportTypes(ConversionContext conversionContext) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTypeFactory().getType( Date.class ), conversionContext.getTypeFactory().getType( Date.class ),
conversionContext.getTypeFactory().getType( ZONE_OFFSET_FQN ) conversionContext.getTypeFactory().getType( ZoneOffset.class )
); );
} }
@ -46,7 +46,7 @@ public class JavaLocalDateToSqlDateConversion extends SimpleConversion {
@Override @Override
protected Set<Type> getFromConversionImportTypes(ConversionContext conversionContext) { protected Set<Type> getFromConversionImportTypes(ConversionContext conversionContext) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTypeFactory().getType( ZONE_OFFSET_FQN ) conversionContext.getTypeFactory().getType( ZoneOffset.class )
); );
} }

View File

@ -5,6 +5,8 @@
*/ */
package org.mapstruct.ap.internal.conversion; package org.mapstruct.ap.internal.conversion;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
@ -15,8 +17,6 @@ import org.mapstruct.ap.internal.util.Collections;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.date; import static org.mapstruct.ap.internal.conversion.ConversionUtils.date;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneId; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneId;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.zonedDateTime; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zonedDateTime;
import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONED_DATE_TIME_FQN;
import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_ID_FQN;
/** /**
* SimpleConversion for mapping {@link java.time.ZonedDateTime} to * SimpleConversion for mapping {@link java.time.ZonedDateTime} to
@ -48,8 +48,8 @@ public class JavaZonedDateTimeToDateConversion extends SimpleConversion {
@Override @Override
protected Set<Type> getFromConversionImportTypes(ConversionContext conversionContext) { protected Set<Type> getFromConversionImportTypes(ConversionContext conversionContext) {
return Collections.asSet( return Collections.asSet(
conversionContext.getTypeFactory().getType( ZONED_DATE_TIME_FQN ), conversionContext.getTypeFactory().getType( ZonedDateTime.class ),
conversionContext.getTypeFactory().getType( ZONE_ID_FQN ) conversionContext.getTypeFactory().getType( ZoneId.class )
); );
} }
} }

View File

@ -34,7 +34,7 @@ public class JodaDateTimeToCalendarConversion extends SimpleConversion {
@Override @Override
protected String getFromExpression(ConversionContext conversionContext) { protected String getFromExpression(ConversionContext conversionContext) {
return "new " + conversionContext.getTargetType().getReferenceName() + "( <SOURCE> )"; return "new " + conversionContext.getTargetType().createReferenceName() + "( <SOURCE> )";
} }
@Override @Override

View File

@ -32,7 +32,7 @@ public class JodaTimeToDateConversion extends SimpleConversion {
@Override @Override
protected String getFromExpression(ConversionContext conversionContext) { protected String getFromExpression(ConversionContext conversionContext) {
return "new " + conversionContext.getTargetType().getReferenceName() + "( <SOURCE> )"; return "new " + conversionContext.getTargetType().createReferenceName() + "( <SOURCE> )";
} }
@Override @Override

View File

@ -224,7 +224,7 @@ public abstract class GeneratedType extends ModelElement {
} }
private boolean needsImportDeclaration(Type typeToAdd) { private boolean needsImportDeclaration(Type typeToAdd) {
if ( !typeToAdd.isImported() ) { if ( !typeToAdd.isToBeImported() ) {
return false; return false;
} }

View File

@ -8,8 +8,11 @@ package org.mapstruct.ap.internal.model.common;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import org.mapstruct.ap.internal.util.JodaTimeConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants;
import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Message;
import org.mapstruct.ap.internal.util.XmlConstants; import org.mapstruct.ap.internal.util.XmlConstants;
@ -89,10 +92,11 @@ final class DateFormatValidatorFactory {
return typesEqualsOneOf( return typesEqualsOneOf(
sourceType, sourceType,
targetType, targetType,
JavaTimeConstants.LOCAL_DATE_FQN, LocalDate.class.getCanonicalName(),
JavaTimeConstants.LOCAL_TIME_FQN, LocalTime.class.getCanonicalName(),
JavaTimeConstants.LOCAL_DATE_TIME_FQN, LocalDateTime.class.getCanonicalName(),
JavaTimeConstants.ZONED_DATE_TIME_FQN ); ZonedDateTime.class.getCanonicalName()
);
} }
private static boolean isJavaUtilDateSupposed(Type sourceType, Type targetType) { private static boolean isJavaUtilDateSupposed(Type sourceType, Type targetType) {

View File

@ -77,13 +77,16 @@ public class Type extends ModelElement implements Comparable<Type> {
private final boolean isIterableType; private final boolean isIterableType;
private final boolean isCollectionType; private final boolean isCollectionType;
private final boolean isMapType; private final boolean isMapType;
private final boolean isImported;
private final boolean isVoid; private final boolean isVoid;
private final boolean isStream; private final boolean isStream;
private final boolean isLiteral; private final boolean isLiteral;
private final List<String> enumConstants; private final List<String> enumConstants;
private final Map<String, String> toBeImportedTypes;
private final Map<String, String> notToBeImportedTypes;
private Boolean isToBeImported;
private Map<String, Accessor> readAccessors = null; private Map<String, Accessor> readAccessors = null;
private Map<String, ExecutableElementAccessor> presenceCheckers = null; private Map<String, ExecutableElementAccessor> presenceCheckers = null;
@ -104,7 +107,10 @@ public class Type extends ModelElement implements Comparable<Type> {
BuilderInfo builderInfo, BuilderInfo builderInfo,
String packageName, String name, String qualifiedName, String packageName, String name, String qualifiedName,
boolean isInterface, boolean isEnumType, boolean isIterableType, boolean isInterface, boolean isEnumType, boolean isIterableType,
boolean isCollectionType, boolean isMapType, boolean isStreamType, boolean isImported, boolean isCollectionType, boolean isMapType, boolean isStreamType,
Map<String, String> toBeImportedTypes,
Map<String, String> notToBeImportedTypes,
Boolean isToBeImported,
boolean isLiteral ) { boolean isLiteral ) {
this.typeUtils = typeUtils; this.typeUtils = typeUtils;
@ -128,7 +134,6 @@ public class Type extends ModelElement implements Comparable<Type> {
this.isCollectionType = isCollectionType; this.isCollectionType = isCollectionType;
this.isMapType = isMapType; this.isMapType = isMapType;
this.isStream = isStreamType; this.isStream = isStreamType;
this.isImported = isImported;
this.isVoid = typeMirror.getKind() == TypeKind.VOID; this.isVoid = typeMirror.getKind() == TypeKind.VOID;
this.isLiteral = isLiteral; this.isLiteral = isLiteral;
@ -148,6 +153,9 @@ public class Type extends ModelElement implements Comparable<Type> {
enumConstants = Collections.emptyList(); enumConstants = Collections.emptyList();
} }
this.isToBeImported = isToBeImported;
this.toBeImportedTypes = toBeImportedTypes;
this.notToBeImportedTypes = notToBeImportedTypes;
this.builderType = BuilderType.create( builderInfo, this, this.typeFactory, this.typeUtils ); this.builderType = BuilderType.create( builderInfo, this, this.typeFactory, this.typeUtils );
} }
//CHECKSTYLE:ON //CHECKSTYLE:ON
@ -169,12 +177,18 @@ public class Type extends ModelElement implements Comparable<Type> {
} }
/** /**
* String that could be used in generated code to reference to this {@link Type}. * Returns a String that could be used in generated code to reference to this {@link Type}.<br>
* <p>
* The first time a name is referred-to it will be marked as to be imported. For instance
* {@code LocalDateTime} can be one of {@code java.time.LocalDateTime} and {@code org.joda.LocalDateTime})
* <p>
* If the {@code java.time} variant is referred to first, the {@code java.time.LocalDateTime} will be imported
* and the {@code org.joda} variant will be referred to with its FQN.
* *
* @return Just the name if this {@link Type} will be imported, otherwise the fully-qualified name. * @return Just the name if this {@link Type} will be imported, otherwise the fully-qualified name.
*/ */
public String getReferenceName() { public String createReferenceName() {
return isImported ? name : qualifiedName; return isToBeImported() ? name : ( shouldUseSimpleName() ? name : qualifiedName );
} }
public List<Type> getTypeParameters() { public List<Type> getTypeParameters() {
@ -314,7 +328,7 @@ public class Type extends ModelElement implements Comparable<Type> {
* @return The name of this type as to be used within import statements. * @return The name of this type as to be used within import statements.
*/ */
public String getImportName() { public String getImportName() {
return isArrayType() ? TypeFactory.trimSimpleClassName( qualifiedName ) : qualifiedName; return isArrayType() ? trimSimpleClassName( qualifiedName ) : qualifiedName;
} }
@Override @Override
@ -341,14 +355,38 @@ public class Type extends ModelElement implements Comparable<Type> {
} }
/** /**
* Whether this type is imported by means of an import statement in the currently generated source file (meaning it * Whether this type is to be imported by means of an import statement in the currently generated source file
* can be referenced in the generated source using its simple name) or not (meaning it has to be referenced using * (it can be referenced in the generated source using its simple name) or not (referenced using the FQN).
* the fully-qualified name).
* *
* @return {@code true} if the type is imported, {@code false} otherwise. * @return {@code true} if the type is imported, {@code false} otherwise.
*/ */
public boolean isImported() { public boolean isToBeImported() {
return isImported; if ( isToBeImported == null ) {
String trimmedName = trimSimpleClassName( name );
if ( notToBeImportedTypes.containsKey( trimmedName ) ) {
isToBeImported = false;
return isToBeImported;
}
String trimmedQualifiedName = trimSimpleClassName( qualifiedName );
String importedType = toBeImportedTypes.get( trimmedName );
isToBeImported = false;
if ( importedType != null ) {
if ( importedType.equals( trimmedQualifiedName ) ) {
isToBeImported = true;
}
}
else {
toBeImportedTypes.put( trimmedName, trimmedQualifiedName );
isToBeImported = true;
}
}
return isToBeImported;
}
private boolean shouldUseSimpleName() {
String fqn = notToBeImportedTypes.get( name );
return this.qualifiedName.equals( fqn );
} }
/** /**
@ -390,7 +428,9 @@ public class Type extends ModelElement implements Comparable<Type> {
isCollectionType, isCollectionType,
isMapType, isMapType,
isStream, isStream,
isImported, toBeImportedTypes,
notToBeImportedTypes,
isToBeImported,
isLiteral isLiteral
); );
} }
@ -431,7 +471,9 @@ public class Type extends ModelElement implements Comparable<Type> {
isCollectionType, isCollectionType,
isMapType, isMapType,
isStream, isStream,
isImported, toBeImportedTypes,
notToBeImportedTypes,
isToBeImported,
isLiteral isLiteral
); );
} }
@ -1004,4 +1046,28 @@ public class Type extends ModelElement implements Comparable<Type> {
return isLiteral; return isLiteral;
} }
/**
* It strips all the {@code []} from the {@code className}.
*
* E.g.
* <pre>
* trimSimpleClassName("String[][][]") -> "String"
* trimSimpleClassName("String[]") -> "String"
* </pre>
*
* @param className that needs to be trimmed
*
* @return the trimmed {@code className}, or {@code null} if the {@code className} was {@code null}
*/
private String trimSimpleClassName(String className) {
if ( className == null ) {
return null;
}
String trimmedClassName = className;
while ( trimmedClassName.endsWith( "[]" ) ) {
trimmedClassName = trimmedClassName.substring( 0, trimmedClassName.length() - 2 );
}
return trimmedClassName;
}
} }

View File

@ -84,13 +84,16 @@ public class TypeFactory {
private final TypeMirror streamType; private final TypeMirror streamType;
private final Map<String, ImplementationType> implementationTypes = new HashMap<>(); private final Map<String, ImplementationType> implementationTypes = new HashMap<>();
private final Map<String, String> importedQualifiedTypesBySimpleName = new HashMap<>(); private final Map<String, String> toBeImportedTypes = new HashMap<>();
private final Map<String, String> notToBeImportedTypes;
public TypeFactory(Elements elementUtils, Types typeUtils, FormattingMessager messager, RoundContext roundContext) { public TypeFactory(Elements elementUtils, Types typeUtils, FormattingMessager messager, RoundContext roundContext,
Map<String, String> notToBeImportedTypes) {
this.elementUtils = elementUtils; this.elementUtils = elementUtils;
this.typeUtils = typeUtils; this.typeUtils = typeUtils;
this.messager = messager; this.messager = messager;
this.roundContext = roundContext; this.roundContext = roundContext;
this.notToBeImportedTypes = notToBeImportedTypes;
iterableType = typeUtils.erasure( elementUtils.getTypeElement( Iterable.class.getCanonicalName() ).asType() ); iterableType = typeUtils.erasure( elementUtils.getTypeElement( Iterable.class.getCanonicalName() ).asType() );
collectionType = collectionType =
@ -197,7 +200,7 @@ public class TypeFactory {
String qualifiedName; String qualifiedName;
TypeElement typeElement; TypeElement typeElement;
Type componentType; Type componentType;
boolean isImported; Boolean toBeImported = null;
if ( mirror.getKind() == TypeKind.DECLARED ) { if ( mirror.getKind() == TypeKind.DECLARED ) {
DeclaredType declaredType = (DeclaredType) mirror; DeclaredType declaredType = (DeclaredType) mirror;
@ -218,7 +221,6 @@ public class TypeFactory {
} }
componentType = null; componentType = null;
isImported = isImported( name, qualifiedName );
} }
else if ( mirror.getKind() == TypeKind.ARRAY ) { else if ( mirror.getKind() == TypeKind.ARRAY ) {
TypeMirror componentTypeMirror = getComponentType( mirror ); TypeMirror componentTypeMirror = getComponentType( mirror );
@ -237,7 +239,6 @@ public class TypeFactory {
name = componentTypeElement.getSimpleName().toString() + arraySuffix; name = componentTypeElement.getSimpleName().toString() + arraySuffix;
packageName = elementUtils.getPackageOf( componentTypeElement ).getQualifiedName().toString(); packageName = elementUtils.getPackageOf( componentTypeElement ).getQualifiedName().toString();
qualifiedName = componentTypeElement.getQualifiedName().toString() + arraySuffix; qualifiedName = componentTypeElement.getQualifiedName().toString() + arraySuffix;
isImported = isImported( name, qualifiedName );
} }
else if (componentTypeMirror.getKind().isPrimitive()) { else if (componentTypeMirror.getKind().isPrimitive()) {
// When the component type is primitive and is annotated with ElementType.TYPE_USE then // When the component type is primitive and is annotated with ElementType.TYPE_USE then
@ -246,13 +247,13 @@ public class TypeFactory {
packageName = null; packageName = null;
// for primitive types only name (e.g. byte, short..) required as qualified name // for primitive types only name (e.g. byte, short..) required as qualified name
qualifiedName = name; qualifiedName = name;
isImported = false; toBeImported = false;
} }
else { else {
name = mirror.toString(); name = mirror.toString();
packageName = null; packageName = null;
qualifiedName = name; qualifiedName = name;
isImported = false; toBeImported = false;
} }
isEnumType = false; isEnumType = false;
@ -268,7 +269,7 @@ public class TypeFactory {
qualifiedName = name; qualifiedName = name;
typeElement = null; typeElement = null;
componentType = null; componentType = null;
isImported = false; toBeImported = false;
} }
return new Type( return new Type(
@ -289,7 +290,9 @@ public class TypeFactory {
isCollectionType, isCollectionType,
isMapType, isMapType,
isStreamType, isStreamType,
isImported, toBeImportedTypes,
notToBeImportedTypes,
toBeImported,
isLiteral isLiteral
); );
} }
@ -509,7 +512,9 @@ public class TypeFactory {
implementationType.isCollectionType(), implementationType.isCollectionType(),
implementationType.isMapType(), implementationType.isMapType(),
implementationType.isStreamType(), implementationType.isStreamType(),
isImported( implementationType.getName(), implementationType.getFullyQualifiedName() ), toBeImportedTypes,
notToBeImportedTypes,
null,
implementationType.isLiteral() implementationType.isLiteral()
); );
return implementation.createNew( replacement ); return implementation.createNew( replacement );
@ -545,24 +550,6 @@ public class TypeFactory {
return arrayType.getComponentType(); return arrayType.getComponentType();
} }
private boolean isImported(String name, String qualifiedName) {
String trimmedName = TypeFactory.trimSimpleClassName( name );
String trimmedQualifiedName = TypeFactory.trimSimpleClassName( qualifiedName );
String importedType = importedQualifiedTypesBySimpleName.get( trimmedName );
boolean imported = false;
if ( importedType != null ) {
if ( importedType.equals( trimmedQualifiedName ) ) {
imported = true;
}
}
else {
importedQualifiedTypesBySimpleName.put( trimmedName, trimmedQualifiedName );
imported = true;
}
return imported;
}
/** /**
* Converts any collection type, e.g. {@code List<T>} to {@code Collection<T>} and any map type, e.g. * Converts any collection type, e.g. {@code List<T>} to {@code Collection<T>} and any map type, e.g.
* {@code HashMap<K,V>} to {@code Map<K,V>}. * {@code HashMap<K,V>} to {@code Map<K,V>}.
@ -643,29 +630,6 @@ public class TypeFactory {
return typeMirror; return typeMirror;
} }
/**
* It strips the all the {@code []} from the {@code className}.
*
* E.g.
* <pre>
* trimSimpleClassName("String[][][]") -> "String"
* trimSimpleClassName("String[]") -> "String"
* </pre>
*
* @param className that needs to be trimmed
*
* @return the trimmed {@code className}, or {@code null} if the {@code className} was {@code null}
*/
static String trimSimpleClassName(String className) {
if ( className == null ) {
return null;
}
String trimmedClassName = className;
while ( trimmedClassName.endsWith( "[]" ) ) {
trimmedClassName = trimmedClassName.substring( 0, trimmedClassName.length() - 2 );
}
return trimmedClassName;
}
/** /**
* Whether the given type is ready to be processed or not. It can be processed if it is not of kind * Whether the given type is ready to be processed or not. It can be processed if it is not of kind

View File

@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.common.TypeFactory;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import org.mapstruct.ap.internal.util.JaxbConstants; import org.mapstruct.ap.internal.util.JaxbConstants;
import org.mapstruct.ap.internal.util.JodaTimeConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants;
import org.mapstruct.ap.internal.util.XmlConstants; import org.mapstruct.ap.internal.util.XmlConstants;
@ -33,21 +32,18 @@ public class BuiltInMappingMethods {
builtInMethods.add( new XmlGregorianCalendarToString( typeFactory ) ); builtInMethods.add( new XmlGregorianCalendarToString( typeFactory ) );
builtInMethods.add( new CalendarToXmlGregorianCalendar( typeFactory ) ); builtInMethods.add( new CalendarToXmlGregorianCalendar( typeFactory ) );
builtInMethods.add( new XmlGregorianCalendarToCalendar( typeFactory ) ); builtInMethods.add( new XmlGregorianCalendarToCalendar( typeFactory ) );
builtInMethods.add( new ZonedDateTimeToXmlGregorianCalendar( typeFactory ) );
} }
if ( isJaxbAvailable( typeFactory ) ) { if ( isJaxbAvailable( typeFactory ) ) {
builtInMethods.add( new JaxbElemToValue( typeFactory ) ); builtInMethods.add( new JaxbElemToValue( typeFactory ) );
} }
builtInMethods.add( new ZonedDateTimeToCalendar( typeFactory ) );
if ( isJava8TimeAvailable( typeFactory ) ) { builtInMethods.add( new CalendarToZonedDateTime( typeFactory ) );
builtInMethods.add( new ZonedDateTimeToCalendar( typeFactory ) ); if ( isXmlGregorianCalendarPresent ) {
builtInMethods.add( new ZonedDateTimeToXmlGregorianCalendar( typeFactory ) ); builtInMethods.add( new XmlGregorianCalendarToLocalDate( typeFactory ) );
builtInMethods.add( new CalendarToZonedDateTime( typeFactory ) ); builtInMethods.add( new LocalDateToXmlGregorianCalendar( typeFactory ) );
if ( isXmlGregorianCalendarPresent ) {
builtInMethods.add( new XmlGregorianCalendarToLocalDate( typeFactory ) );
builtInMethods.add( new LocalDateToXmlGregorianCalendar( typeFactory ) );
}
} }
if ( isJodaTimeAvailable( typeFactory ) && isXmlGregorianCalendarPresent ) { if ( isJodaTimeAvailable( typeFactory ) && isXmlGregorianCalendarPresent ) {
@ -66,10 +62,6 @@ public class BuiltInMappingMethods {
return JaxbConstants.isJaxbElementPresent() && typeFactory.isTypeAvailable( JaxbConstants.JAXB_ELEMENT_FQN ); return JaxbConstants.isJaxbElementPresent() && typeFactory.isTypeAvailable( JaxbConstants.JAXB_ELEMENT_FQN );
} }
private static boolean isJava8TimeAvailable(TypeFactory typeFactory) {
return typeFactory.isTypeAvailable( JavaTimeConstants.ZONED_DATE_TIME_FQN );
}
private static boolean isXmlGregorianCalendarAvailable(TypeFactory typeFactory) { private static boolean isXmlGregorianCalendarAvailable(TypeFactory typeFactory) {
return XmlConstants.isXmlGregorianCalendarPresent() && return XmlConstants.isXmlGregorianCalendarPresent() &&
typeFactory.isTypeAvailable( XmlConstants.JAVAX_XML_DATATYPE_XMLGREGORIAN_CALENDAR ); typeFactory.isTypeAvailable( XmlConstants.JAVAX_XML_DATATYPE_XMLGREGORIAN_CALENDAR );

View File

@ -12,7 +12,6 @@ import java.util.Set;
import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.common.TypeFactory;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.util.Collections.asSet;
@ -28,7 +27,7 @@ public class CalendarToZonedDateTime extends BuiltInMethod {
private final Set<Type> importedTypes; private final Set<Type> importedTypes;
CalendarToZonedDateTime(TypeFactory typeFactory) { CalendarToZonedDateTime(TypeFactory typeFactory) {
this.returnType = typeFactory.getType( JavaTimeConstants.ZONED_DATE_TIME_FQN ); this.returnType = typeFactory.getType( ZonedDateTime.class );
this.parameter = new Parameter( "cal", typeFactory.getType( Calendar.class ) ); this.parameter = new Parameter( "cal", typeFactory.getType( Calendar.class ) );
this.importedTypes = asSet( returnType, parameter.getType() ); this.importedTypes = asSet( returnType, parameter.getType() );
} }

View File

@ -13,7 +13,6 @@ import java.util.TimeZone;
import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.common.TypeFactory;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.util.Collections.asSet;
@ -29,7 +28,7 @@ public class ZonedDateTimeToCalendar extends BuiltInMethod {
ZonedDateTimeToCalendar(TypeFactory typeFactory) { ZonedDateTimeToCalendar(TypeFactory typeFactory) {
this.returnType = typeFactory.getType( Calendar.class ); this.returnType = typeFactory.getType( Calendar.class );
this.parameter = new Parameter( "dateTime", typeFactory.getType( JavaTimeConstants.ZONED_DATE_TIME_FQN ) ); this.parameter = new Parameter( "dateTime", typeFactory.getType( ZonedDateTime.class ) );
this.importedTypes = asSet( returnType, parameter.getType(), typeFactory.getType( TimeZone.class ) ); this.importedTypes = asSet( returnType, parameter.getType(), typeFactory.getType( TimeZone.class ) );
} }

View File

@ -5,6 +5,7 @@
*/ */
package org.mapstruct.ap.internal.processor; package org.mapstruct.ap.internal.processor;
import java.util.Map;
import javax.annotation.processing.Filer; import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager; import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;
@ -41,7 +42,7 @@ public class DefaultModelElementProcessorContext implements ProcessorContext {
private final AccessorNamingUtils accessorNaming; private final AccessorNamingUtils accessorNaming;
public DefaultModelElementProcessorContext(ProcessingEnvironment processingEnvironment, Options options, public DefaultModelElementProcessorContext(ProcessingEnvironment processingEnvironment, Options options,
RoundContext roundContext) { RoundContext roundContext, Map<String, String> notToBeImported) {
this.processingEnvironment = processingEnvironment; this.processingEnvironment = processingEnvironment;
this.messager = new DelegatingMessager( processingEnvironment.getMessager() ); this.messager = new DelegatingMessager( processingEnvironment.getMessager() );
@ -52,7 +53,8 @@ public class DefaultModelElementProcessorContext implements ProcessorContext {
processingEnvironment.getElementUtils(), processingEnvironment.getElementUtils(),
delegatingTypes, delegatingTypes,
messager, messager,
roundContext roundContext,
notToBeImported
); );
this.options = options; this.options = options;
} }

View File

@ -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.util;
/**
* Helper holding Java time full qualified class names for conversion registration
*/
public final class JavaTimeConstants {
public static final String ZONED_DATE_TIME_FQN = "java.time.ZonedDateTime";
public static final String ZONE_OFFSET_FQN = "java.time.ZoneOffset";
public static final String ZONE_ID_FQN = "java.time.ZoneId";
public static final String LOCAL_DATE_TIME_FQN = "java.time.LocalDateTime";
public static final String LOCAL_DATE_FQN = "java.time.LocalDate";
public static final String LOCAL_TIME_FQN = "java.time.LocalTime";
public static final String DATE_TIME_FORMATTER_FQN = "java.time.format.DateTimeFormatter";
public static final String INSTANT = "java.time.Instant";
private JavaTimeConstants() {
}
}

View File

@ -12,6 +12,6 @@
<#elseif wildCardSuperBound> <#elseif wildCardSuperBound>
? super <@includeModel object=typeBound /> ? super <@includeModel object=typeBound />
<#else> <#else>
<#if ext.asVarArgs!false>${referenceName?remove_ending("[]")}...<#else>${referenceName}</#if></#if><#if (!ext.raw?? && typeParameters?size > 0) ><<#list typeParameters as typeParameter><@includeModel object=typeParameter /><#if typeParameter_has_next>, </#if></#list>> <#if ext.asVarArgs!false>${createReferenceName()?remove_ending("[]")}...<#else>${createReferenceName()}</#if></#if><#if (!ext.raw?? && typeParameters?size > 0) ><<#list typeParameters as typeParameter><@includeModel object=typeParameter /><#if typeParameter_has_next>, </#if></#list>>
</#if> </#if>
</@compress> </@compress>

View File

@ -8,6 +8,11 @@ package org.mapstruct.ap.internal.model.common;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List; import java.util.List;
import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationMirror;
@ -16,7 +21,6 @@ import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVisitor; import javax.lang.model.type.TypeVisitor;
import org.junit.Test; import org.junit.Test;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import org.mapstruct.ap.internal.util.JodaTimeConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
@ -113,25 +117,25 @@ public class DateFormatValidatorFactoryTest {
Type targetType = typeWithFQN( JAVA_LANG_STRING ); Type targetType = typeWithFQN( JAVA_LANG_STRING );
Type sourceType = typeWithFQN( JavaTimeConstants.ZONED_DATE_TIME_FQN ); Type sourceType = typeWithFQN( ZonedDateTime.class.getCanonicalName() );
assertInvalidDateFormat( sourceType, targetType ); assertInvalidDateFormat( sourceType, targetType );
assertInvalidDateFormat( targetType, sourceType ); assertInvalidDateFormat( targetType, sourceType );
assertValidDateFormat( sourceType, targetType ); assertValidDateFormat( sourceType, targetType );
assertValidDateFormat( targetType, sourceType ); assertValidDateFormat( targetType, sourceType );
sourceType = typeWithFQN( JavaTimeConstants.LOCAL_DATE_FQN ); sourceType = typeWithFQN( LocalDate.class.getCanonicalName() );
assertInvalidDateFormat( sourceType, targetType ); assertInvalidDateFormat( sourceType, targetType );
assertInvalidDateFormat( targetType, sourceType ); assertInvalidDateFormat( targetType, sourceType );
assertValidDateFormat( sourceType, targetType ); assertValidDateFormat( sourceType, targetType );
assertValidDateFormat( targetType, sourceType ); assertValidDateFormat( targetType, sourceType );
sourceType = typeWithFQN( JavaTimeConstants.LOCAL_DATE_TIME_FQN ); sourceType = typeWithFQN( LocalDateTime.class.getCanonicalName() );
assertInvalidDateFormat( sourceType, targetType ); assertInvalidDateFormat( sourceType, targetType );
assertInvalidDateFormat( targetType, sourceType ); assertInvalidDateFormat( targetType, sourceType );
assertValidDateFormat( sourceType, targetType ); assertValidDateFormat( sourceType, targetType );
assertValidDateFormat( targetType, sourceType ); assertValidDateFormat( targetType, sourceType );
sourceType = typeWithFQN( JavaTimeConstants.LOCAL_TIME_FQN ); sourceType = typeWithFQN( LocalTime.class.getCanonicalName() );
assertInvalidDateFormat( sourceType, targetType ); assertInvalidDateFormat( sourceType, targetType );
assertInvalidDateFormat( targetType, sourceType ); assertInvalidDateFormat( targetType, sourceType );
assertValidDateFormat( sourceType, targetType ); assertValidDateFormat( sourceType, targetType );
@ -171,6 +175,8 @@ public class DateFormatValidatorFactoryTest {
false, false,
false, false,
false, false,
new HashMap<>( ),
new HashMap<>( ),
false, false,
false); false);
} }

View File

@ -8,6 +8,8 @@ package org.mapstruct.ap.internal.model.common;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List; import java.util.List;
import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationMirror;
@ -20,7 +22,6 @@ import javax.tools.Diagnostic;
import org.junit.Test; import org.junit.Test;
import org.mapstruct.ap.internal.util.FormattingMessager; import org.mapstruct.ap.internal.util.FormattingMessager;
import org.mapstruct.ap.internal.util.JavaTimeConstants;
import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Message;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
@ -62,7 +63,7 @@ public class DefaultConversionContextTest {
@Test @Test
public void testInvalidDateFormatValidation() { public void testInvalidDateFormatValidation() {
Type type = typeWithFQN( JavaTimeConstants.ZONED_DATE_TIME_FQN ); Type type = typeWithFQN( ZonedDateTime.class.getCanonicalName() );
StatefulMessagerMock statefulMessagerMock = new StatefulMessagerMock(); StatefulMessagerMock statefulMessagerMock = new StatefulMessagerMock();
new DefaultConversionContext( new DefaultConversionContext(
null, null,
@ -76,7 +77,7 @@ public class DefaultConversionContextTest {
@Test @Test
public void testNullDateFormatValidation() { public void testNullDateFormatValidation() {
Type type = typeWithFQN( JavaTimeConstants.ZONED_DATE_TIME_FQN ); Type type = typeWithFQN( ZonedDateTime.class.getCanonicalName() );
StatefulMessagerMock statefulMessagerMock = new StatefulMessagerMock(); StatefulMessagerMock statefulMessagerMock = new StatefulMessagerMock();
new DefaultConversionContext( new DefaultConversionContext(
null, null,
@ -122,6 +123,8 @@ public class DefaultConversionContextTest {
false, false,
false, false,
false, false,
new HashMap<>( ),
new HashMap<>( ),
false, false,
false); false);
} }

View File

@ -1,50 +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.common;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class TypeFactoryTest {
@Test
public void shouldReturnNullIfNoClassNameIsProvided() {
String result = TypeFactory.trimSimpleClassName( null );
assertThat( result ).isNull();
}
@Test
public void shouldNotModifyClassNameIfNotAnArray() {
String className = "SimpleClass";
String result = TypeFactory.trimSimpleClassName( className );
assertThat( result ).isEqualTo( className );
}
@Test
public void shouldTrimOneDimensionalArray() {
String result = TypeFactory.trimSimpleClassName( "SimpleClass[]" );
assertThat( result ).isEqualTo( "SimpleClass" );
}
@Test
public void shouldTrimTwoDimensionalArray() {
String result = TypeFactory.trimSimpleClassName( "SimpleClass[][]" );
assertThat( result ).isEqualTo( "SimpleClass" );
}
@Test
public void shouldTrimMultiDimensionalArray() {
String result = TypeFactory.trimSimpleClassName( "SimpleClass[][][][][]" );
assertThat( result ).isEqualTo( "SimpleClass" );
}
}

View File

@ -0,0 +1,17 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._1576.java8;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface Issue1576Mapper {
Issue1576Mapper INSTANCE = Mappers.getMapper( Issue1576Mapper.class );
Target map( Source source );
}

View File

@ -0,0 +1,32 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._1576.java8;
import org.junit.Rule;
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 org.mapstruct.ap.testutil.runner.GeneratedSource;
@IssueKey("1576")
@RunWith(AnnotationProcessorTestRunner.class)
@WithClasses( { Issue1576Mapper.class, Source.class, Target.class })
public class Issue1576Test {
@Rule
public final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor(
Issue1576Mapper.class
);
@Test
public void testLocalDateTimeIsImported() {
Issue1576Mapper.INSTANCE.map( new Source() );
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._1576.java8;
import java.util.Date;
public class Source {
private Date localDateTime;
private Date localDate;
private String localTime;
private Date zonedDateTime;
private Date instant;
public Date getLocalDateTime() {
return localDateTime;
}
public void setLocalDateTime(Date localDateTime) {
this.localDateTime = localDateTime;
}
public Date getLocalDate() {
return localDate;
}
public void setLocalDate(Date localDate) {
this.localDate = localDate;
}
public String getLocalTime() {
return localTime;
}
public void setLocalTime(String localTime) {
this.localTime = localTime;
}
public Date getZonedDateTime() {
return zonedDateTime;
}
public void setZonedDateTime(Date zonedDateTime) {
this.zonedDateTime = zonedDateTime;
}
public Date getInstant() {
return instant;
}
public void setInstant(Date instant) {
this.instant = instant;
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._1576.java8;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
public class Target {
private LocalDateTime localDateTime;
private LocalDate localDate;
private LocalTime localTime;
private ZonedDateTime zonedDateTime;
private Instant instant;
public LocalDateTime getLocalDateTime() {
return localDateTime;
}
public void setLocalDateTime(LocalDateTime localDateTime) {
this.localDateTime = localDateTime;
}
public LocalDate getLocalDate() {
return localDate;
}
public void setLocalDate(LocalDate localDate) {
this.localDate = localDate;
}
public LocalTime getLocalTime() {
return localTime;
}
public void setLocalTime(LocalTime localTime) {
this.localTime = localTime;
}
public ZonedDateTime getZonedDateTime() {
return zonedDateTime;
}
public void setZonedDateTime(ZonedDateTime zonedDateTime) {
this.zonedDateTime = zonedDateTime;
}
public Instant getInstant() {
return instant;
}
public void setInstant(Instant instant) {
this.instant = instant;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.test.bugs._1576.java8;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2018-11-05T21:40:12+0100",
comments = "version: , compiler: javac, environment: Java 1.8.0_181 (Oracle Corporation)"
)
public class Issue1576MapperImpl implements Issue1576Mapper {
@Override
public Target map(Source source) {
if ( source == null ) {
return null;
}
Target target = new Target();
if ( source.getLocalDateTime() != null ) {
target.setLocalDateTime( LocalDateTime.ofInstant( source.getLocalDateTime().toInstant(), ZoneId.of( "UTC" ) ) );
}
if ( source.getLocalDate() != null ) {
target.setLocalDate( LocalDateTime.ofInstant( source.getLocalDate().toInstant(), ZoneOffset.UTC ).toLocalDate() );
}
if ( source.getLocalTime() != null ) {
target.setLocalTime( LocalTime.parse( source.getLocalTime() ) );
}
if ( source.getZonedDateTime() != null ) {
target.setZonedDateTime( ZonedDateTime.ofInstant( source.getZonedDateTime().toInstant(), ZoneId.systemDefault() ) );
}
if ( source.getInstant() != null ) {
target.setInstant( source.getInstant().toInstant() );
}
return target;
}
}