mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#120 Method and BuiltInMethod implement a common interface that can be used for matching.
This commit is contained in:
parent
08b6008ed1
commit
2471edcf69
@ -18,103 +18,27 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.builtin;
|
package org.mapstruct.ap.builtin;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.annotation.processing.Messager;
|
|
||||||
import javax.tools.Diagnostic;
|
|
||||||
import org.mapstruct.ap.model.common.Type;
|
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
import org.mapstruct.ap.util.Strings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Registry for all build in methods.
|
||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class BuiltInMappingMethods {
|
public class BuiltInMappingMethods extends HashSet<BuiltInMethod> {
|
||||||
|
|
||||||
private final Set<BuiltInMappingMethod> builtInMethods = new HashSet<BuiltInMappingMethod>();
|
public BuiltInMappingMethods( TypeFactory typeFactory ) {
|
||||||
private final Messager messager;
|
|
||||||
|
|
||||||
public BuiltInMappingMethods( Messager messager, TypeFactory typeFactory ) {
|
add( new JaxbElemToValue( typeFactory ) );
|
||||||
this.messager = messager;
|
add( new ListOfJaxbElemToListOfValue( typeFactory ) );
|
||||||
|
add( new DateToXmlGregorianCalendar( typeFactory ) );
|
||||||
builtInMethods.add( new JaxbElemToValue( typeFactory ) );
|
add( new XmlGregorianCalendarToDate( typeFactory ) );
|
||||||
builtInMethods.add( new ListOfJaxbElemToListOfValue( typeFactory ) );
|
add( new StringToXmlGregorianCalendar( typeFactory ) );
|
||||||
builtInMethods.add( new DateToXmlGregorianCalendar( typeFactory ) );
|
add( new XmlGregorianCalendarToString( typeFactory ) );
|
||||||
builtInMethods.add( new XmlGregorianCalendarToDate( typeFactory ) );
|
add( new CalendarToXmlGregorianCalendar( typeFactory ) );
|
||||||
builtInMethods.add( new StringToXmlGregorianCalendar( typeFactory ) );
|
add( new XmlGregorianCalendarToCalendar( typeFactory ) );
|
||||||
builtInMethods.add( new XmlGregorianCalendarToString( typeFactory ) );
|
|
||||||
builtInMethods.add( new CalendarToXmlGregorianCalendar( typeFactory ) );
|
|
||||||
builtInMethods.add( new XmlGregorianCalendarToCalendar( typeFactory ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The method looks for a match on equal source type and best matching target type (minimum distance) TODO:
|
|
||||||
* investigate whether also the best matching source type should be investigating iso equal.
|
|
||||||
*
|
|
||||||
* @param sourceType
|
|
||||||
* @param targetType
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public BuiltInMappingMethod getConversion( Type sourceType, Type targetType ) {
|
|
||||||
|
|
||||||
List<BuiltInMappingMethod> candidates = new ArrayList<BuiltInMappingMethod>();
|
|
||||||
int bestMatchingTargetTypeDistance = Integer.MAX_VALUE;
|
|
||||||
for ( BuiltInMappingMethod entry : builtInMethods ) {
|
|
||||||
|
|
||||||
if ( targetType.erasure().isAssignableTo( entry.target() )
|
|
||||||
&& sourceType.erasure().isAssignableTo( entry.source() ) ) {
|
|
||||||
|
|
||||||
if ( entry.doGenericsMatch( sourceType, targetType ) ) {
|
|
||||||
int sourceTypeDistance = targetType.distanceTo( entry.target() );
|
|
||||||
bestMatchingTargetTypeDistance
|
|
||||||
= addToCandidateListIfMinimal(
|
|
||||||
candidates,
|
|
||||||
bestMatchingTargetTypeDistance,
|
|
||||||
entry,
|
|
||||||
sourceTypeDistance );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( candidates.isEmpty() ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( candidates.size() > 1 ) {
|
|
||||||
// print a warning if we find more than one method with minimum source type distance
|
|
||||||
List<String> builtInMethodNames = new ArrayList<String>();
|
|
||||||
for ( BuiltInMappingMethod candidate : candidates ) {
|
|
||||||
builtInMethodNames.add( candidate.getName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
messager.printMessage(
|
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"MapStruct error. Conflicting build-in methods %s for sourceType: %s, targetTypes %s.",
|
|
||||||
Strings.join( builtInMethodNames, ", " ),
|
|
||||||
sourceType,
|
|
||||||
targetType )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return candidates.get( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
private int addToCandidateListIfMinimal( List<BuiltInMappingMethod> candidatesWithBestMathingType,
|
|
||||||
int bestMatchingTypeDistance, BuiltInMappingMethod builtInMethod, int currentTypeDistance ) {
|
|
||||||
if ( currentTypeDistance == bestMatchingTypeDistance ) {
|
|
||||||
candidatesWithBestMathingType.add( builtInMethod );
|
|
||||||
}
|
|
||||||
else if ( currentTypeDistance < bestMatchingTypeDistance ) {
|
|
||||||
bestMatchingTypeDistance = currentTypeDistance;
|
|
||||||
|
|
||||||
candidatesWithBestMathingType.clear();
|
|
||||||
candidatesWithBestMathingType.add( builtInMethod );
|
|
||||||
}
|
|
||||||
return bestMatchingTypeDistance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,15 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.builtin;
|
package org.mapstruct.ap.builtin;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.xml.datatype.DatatypeConfigurationException;
|
import javax.xml.datatype.DatatypeConfigurationException;
|
||||||
import javax.xml.datatype.DatatypeFactory;
|
import javax.xml.datatype.DatatypeFactory;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
import org.mapstruct.ap.model.MethodReference;
|
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
@ -36,25 +34,17 @@ import static org.mapstruct.ap.util.Collections.asSet;
|
|||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class CalendarToXmlGregorianCalendar extends BuiltInMappingMethod {
|
public class CalendarToXmlGregorianCalendar extends BuiltInMethod {
|
||||||
|
|
||||||
private static final Class SOURCE = Calendar.class;
|
private final Parameter parameter;
|
||||||
private static final Class TARGET = XMLGregorianCalendar.class;
|
private final Type returnType;
|
||||||
|
|
||||||
private final TypeFactory typeFactory;
|
private final TypeFactory typeFactory;
|
||||||
|
|
||||||
public CalendarToXmlGregorianCalendar( TypeFactory typeFactory ) {
|
public CalendarToXmlGregorianCalendar( TypeFactory typeFactory ) {
|
||||||
this.typeFactory = typeFactory;
|
this.typeFactory = typeFactory;
|
||||||
}
|
this.parameter = typeFactory.createParameter( "cal ", Calendar.class );
|
||||||
|
this.returnType = typeFactory.getType( XMLGregorianCalendar.class );
|
||||||
@Override
|
|
||||||
public MethodReference createMethodReference() {
|
|
||||||
return new MethodReference(
|
|
||||||
getName(),
|
|
||||||
asList( new Parameter[] { typeFactory.createParameter( "cal", SOURCE ) } ),
|
|
||||||
typeFactory.getType( TARGET ),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,12 +55,12 @@ public class CalendarToXmlGregorianCalendar extends BuiltInMappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type source() {
|
public Parameter getParameter() {
|
||||||
return typeFactory.getType( SOURCE ).erasure();
|
return parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type target() {
|
public Type getReturnType() {
|
||||||
return typeFactory.getType( TARGET ).erasure();
|
return returnType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,15 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.builtin;
|
package org.mapstruct.ap.builtin;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.xml.datatype.DatatypeConfigurationException;
|
import javax.xml.datatype.DatatypeConfigurationException;
|
||||||
import javax.xml.datatype.DatatypeFactory;
|
import javax.xml.datatype.DatatypeFactory;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
import org.mapstruct.ap.model.MethodReference;
|
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
@ -36,25 +34,17 @@ import static org.mapstruct.ap.util.Collections.asSet;
|
|||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class DateToXmlGregorianCalendar extends BuiltInMappingMethod {
|
public class DateToXmlGregorianCalendar extends BuiltInMethod {
|
||||||
|
|
||||||
private static final Class SOURCE = Date.class;
|
private final Parameter parameter;
|
||||||
private static final Class TARGET = XMLGregorianCalendar.class;
|
private final Type returnType;
|
||||||
|
|
||||||
private final TypeFactory typeFactory;
|
private final TypeFactory typeFactory;
|
||||||
|
|
||||||
public DateToXmlGregorianCalendar( TypeFactory typeFactory ) {
|
public DateToXmlGregorianCalendar( TypeFactory typeFactory ) {
|
||||||
this.typeFactory = typeFactory;
|
this.typeFactory = typeFactory;
|
||||||
}
|
this.parameter = typeFactory.createParameter( "date", Date.class );
|
||||||
|
this.returnType = typeFactory.getType( XMLGregorianCalendar.class );
|
||||||
@Override
|
|
||||||
public MethodReference createMethodReference() {
|
|
||||||
return new MethodReference(
|
|
||||||
getName(),
|
|
||||||
asList( new Parameter[] { typeFactory.createParameter( "date", SOURCE ) } ),
|
|
||||||
typeFactory.getType( TARGET ),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,12 +55,12 @@ public class DateToXmlGregorianCalendar extends BuiltInMappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type source() {
|
public Parameter getParameter() {
|
||||||
return typeFactory.getType( SOURCE ).erasure();
|
return parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type target() {
|
public Type getReturnType() {
|
||||||
return typeFactory.getType( TARGET ).erasure();
|
return returnType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.builtin;
|
package org.mapstruct.ap.builtin;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import javax.xml.bind.JAXBElement;
|
import javax.xml.bind.JAXBElement;
|
||||||
import org.mapstruct.ap.model.MethodReference;
|
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
@ -30,29 +28,18 @@ import org.mapstruct.ap.model.common.TypeFactory;
|
|||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class JaxbElemToValue extends BuiltInMappingMethod {
|
public class JaxbElemToValue extends BuiltInMethod {
|
||||||
|
|
||||||
private static final Class SOURCE = JAXBElement.class;
|
private final Parameter parameter;
|
||||||
private static final Class TARGET = Object.class;
|
private final Type returnType;
|
||||||
|
|
||||||
private final TypeFactory typeFactory;
|
|
||||||
|
|
||||||
public JaxbElemToValue( TypeFactory typeFactory ) {
|
public JaxbElemToValue( TypeFactory typeFactory ) {
|
||||||
this.typeFactory = typeFactory;
|
this.parameter = typeFactory.createParameter( "element", JAXBElement.class );
|
||||||
|
this.returnType = typeFactory.getType( Object.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodReference createMethodReference() {
|
public boolean doTypeVarsMatch(Type sourceType, Type targetType) {
|
||||||
return new MethodReference(
|
|
||||||
getName(),
|
|
||||||
asList( new Parameter[] { typeFactory.createParameter( "element", SOURCE ) } ),
|
|
||||||
typeFactory.getType( TARGET ),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doGenericsMatch(Type sourceType, Type targetType) {
|
|
||||||
boolean match = false;
|
boolean match = false;
|
||||||
if (sourceType.getTypeParameters().size() == 1) {
|
if (sourceType.getTypeParameters().size() == 1) {
|
||||||
match = sourceType.getTypeParameters().get( 0 ).equals( targetType );
|
match = sourceType.getTypeParameters().get( 0 ).equals( targetType );
|
||||||
@ -61,12 +48,12 @@ public class JaxbElemToValue extends BuiltInMappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type source() {
|
public Parameter getParameter() {
|
||||||
return typeFactory.getType( SOURCE ).erasure();
|
return parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type target() {
|
public Type getReturnType() {
|
||||||
return typeFactory.getType( TARGET ).erasure();
|
return returnType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.builtin;
|
package org.mapstruct.ap.builtin;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.xml.bind.JAXBElement;
|
import javax.xml.bind.JAXBElement;
|
||||||
import org.mapstruct.ap.model.MethodReference;
|
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
@ -31,36 +29,24 @@ import org.mapstruct.ap.model.common.TypeFactory;
|
|||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class ListOfJaxbElemToListOfValue extends BuiltInMappingMethod {
|
public class ListOfJaxbElemToListOfValue extends BuiltInMethod {
|
||||||
|
|
||||||
private static final Class SOURCE = List.class;
|
private final Parameter parameter;
|
||||||
private static final Class TARGET = List.class;
|
private final Type returnType;
|
||||||
private static final Class TARGET_PARAM = JAXBElement.class;
|
private final Type genericParam;
|
||||||
|
|
||||||
private final TypeFactory typeFactory;
|
|
||||||
|
|
||||||
public ListOfJaxbElemToListOfValue( TypeFactory typeFactory ) {
|
public ListOfJaxbElemToListOfValue( TypeFactory typeFactory ) {
|
||||||
this.typeFactory = typeFactory;
|
this.parameter = typeFactory.createParameter( "elementList", List.class );
|
||||||
|
this.returnType = typeFactory.getType( List.class );
|
||||||
|
this.genericParam = typeFactory.getType( JAXBElement.class ).erasure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodReference createMethodReference() {
|
public boolean doTypeVarsMatch(Type sourceType, Type targetType) {
|
||||||
return new MethodReference(
|
|
||||||
getName(),
|
|
||||||
asList( new Parameter[] { typeFactory.createParameter( "elementList", SOURCE ) } ),
|
|
||||||
typeFactory.getType( TARGET ),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doGenericsMatch(Type sourceType, Type targetType) {
|
|
||||||
boolean match = false;
|
boolean match = false;
|
||||||
if ( ( sourceType.getTypeParameters().size() == 1 )
|
if ( ( sourceType.getTypeParameters().size() == 1 ) && ( targetType.getTypeParameters().size() == 1 ) ) {
|
||||||
&& ( targetType.getTypeParameters().size() == 1 ) ) {
|
|
||||||
Type typeParam = sourceType.getTypeParameters().get( 0 );
|
Type typeParam = sourceType.getTypeParameters().get( 0 );
|
||||||
if ( typeParam.erasure().equals( typeFactory.getType( TARGET_PARAM ).erasure() ) &&
|
if ( typeParam.erasure().equals( genericParam ) && ( typeParam.getTypeParameters().size() == 1 ) ) {
|
||||||
( typeParam.getTypeParameters().size() == 1 ) ) {
|
|
||||||
match = typeParam.getTypeParameters().get( 0 ).equals( targetType.getTypeParameters().get( 0 ) );
|
match = typeParam.getTypeParameters().get( 0 ).equals( targetType.getTypeParameters().get( 0 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,12 +54,12 @@ public class ListOfJaxbElemToListOfValue extends BuiltInMappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type source() {
|
public Parameter getParameter() {
|
||||||
return typeFactory.getType( SOURCE ).erasure();
|
return parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type target() {
|
public Type getReturnType() {
|
||||||
return typeFactory.getType( TARGET ).erasure();
|
return returnType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,12 @@ package org.mapstruct.ap.builtin;
|
|||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.xml.datatype.DatatypeConfigurationException;
|
import javax.xml.datatype.DatatypeConfigurationException;
|
||||||
import javax.xml.datatype.DatatypeFactory;
|
import javax.xml.datatype.DatatypeFactory;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
import org.mapstruct.ap.model.MethodReference;
|
|
||||||
import org.mapstruct.ap.model.common.ConversionContext;
|
import org.mapstruct.ap.model.common.ConversionContext;
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
@ -39,26 +37,18 @@ import static org.mapstruct.ap.util.Collections.asSet;
|
|||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class StringToXmlGregorianCalendar extends BuiltInMappingMethod {
|
public class StringToXmlGregorianCalendar extends BuiltInMethod {
|
||||||
|
|
||||||
private static final Class SOURCE = String.class;
|
private final Parameter parameter;
|
||||||
private static final Class TARGET = XMLGregorianCalendar.class;
|
private final Type returnType;
|
||||||
|
|
||||||
private final TypeFactory typeFactory;
|
private final TypeFactory typeFactory;
|
||||||
private ConversionContext conversionContext;
|
|
||||||
|
|
||||||
public StringToXmlGregorianCalendar( TypeFactory typeFactory ) {
|
public StringToXmlGregorianCalendar( TypeFactory typeFactory ) {
|
||||||
this.typeFactory = typeFactory;
|
this.typeFactory = typeFactory;
|
||||||
}
|
this.parameter = typeFactory.createParameter( "date" , String.class );
|
||||||
|
this.returnType = typeFactory.getType( XMLGregorianCalendar.class );
|
||||||
|
|
||||||
@Override
|
|
||||||
public MethodReference createMethodReference() {
|
|
||||||
return new MethodReference(
|
|
||||||
getName(),
|
|
||||||
asList( new Parameter[] { typeFactory.createParameter( "date" , SOURCE ) } ),
|
|
||||||
typeFactory.getType( TARGET ),
|
|
||||||
getContextParm()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,21 +62,17 @@ public class StringToXmlGregorianCalendar extends BuiltInMappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type source() {
|
public Parameter getParameter() {
|
||||||
return typeFactory.getType( SOURCE ).erasure();
|
return parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type target() {
|
public Type getReturnType() {
|
||||||
return typeFactory.getType( TARGET ).erasure();
|
return returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setConversionContext(ConversionContext conversionContext) {
|
public String getContextParameter(ConversionContext conversionContext) {
|
||||||
this.conversionContext = conversionContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getContextParm() {
|
|
||||||
return conversionContext.getDateFormat() != null ? "\"" + conversionContext.getDateFormat() + "\"" : "null";
|
return conversionContext.getDateFormat() != null ? "\"" + conversionContext.getDateFormat() + "\"" : "null";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.builtin;
|
package org.mapstruct.ap.builtin;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
import org.mapstruct.ap.model.MethodReference;
|
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
@ -31,34 +29,23 @@ import org.mapstruct.ap.model.common.TypeFactory;
|
|||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class XmlGregorianCalendarToCalendar extends BuiltInMappingMethod {
|
public class XmlGregorianCalendarToCalendar extends BuiltInMethod {
|
||||||
|
|
||||||
private static final Class SOURCE = XMLGregorianCalendar.class;
|
private final Parameter parameter;
|
||||||
private static final Class TARGET = Calendar.class;
|
private final Type returnType;
|
||||||
|
|
||||||
private final TypeFactory typeFactory;
|
|
||||||
|
|
||||||
public XmlGregorianCalendarToCalendar( TypeFactory typeFactory ) {
|
public XmlGregorianCalendarToCalendar( TypeFactory typeFactory ) {
|
||||||
this.typeFactory = typeFactory;
|
this.parameter = typeFactory.createParameter( "xcal", XMLGregorianCalendar.class );
|
||||||
|
this.returnType = typeFactory.getType( Calendar.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodReference createMethodReference() {
|
public Parameter getParameter() {
|
||||||
return new MethodReference(
|
return parameter;
|
||||||
getName(),
|
|
||||||
asList( new Parameter[] { typeFactory.createParameter( "xcal", SOURCE ) } ),
|
|
||||||
typeFactory.getType( TARGET ),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type source() {
|
public Type getReturnType() {
|
||||||
return typeFactory.getType( SOURCE ).erasure();
|
return returnType;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type target() {
|
|
||||||
return typeFactory.getType( TARGET ).erasure();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.builtin;
|
package org.mapstruct.ap.builtin;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
import org.mapstruct.ap.model.MethodReference;
|
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
@ -31,34 +29,23 @@ import org.mapstruct.ap.model.common.TypeFactory;
|
|||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class XmlGregorianCalendarToDate extends BuiltInMappingMethod {
|
public class XmlGregorianCalendarToDate extends BuiltInMethod {
|
||||||
|
|
||||||
private static final Class SOURCE = XMLGregorianCalendar.class;
|
private final Parameter parameter;
|
||||||
private static final Class TARGET = Date.class;
|
private final Type returnType;
|
||||||
|
|
||||||
private final TypeFactory typeFactory;
|
|
||||||
|
|
||||||
public XmlGregorianCalendarToDate( TypeFactory typeFactory ) {
|
public XmlGregorianCalendarToDate( TypeFactory typeFactory ) {
|
||||||
this.typeFactory = typeFactory;
|
this.parameter = typeFactory.createParameter( "xcal", XMLGregorianCalendar.class );
|
||||||
|
this.returnType = typeFactory.getType( Date.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodReference createMethodReference() {
|
public Parameter getParameter() {
|
||||||
return new MethodReference(
|
return parameter;
|
||||||
getName(),
|
|
||||||
asList( new Parameter[] { typeFactory.createParameter( "xcal", SOURCE ) } ),
|
|
||||||
typeFactory.getType( TARGET ),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type source() {
|
public Type getReturnType() {
|
||||||
return typeFactory.getType( SOURCE ).erasure();
|
return returnType;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type target() {
|
|
||||||
return typeFactory.getType( TARGET ).erasure();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.builtin;
|
package org.mapstruct.ap.builtin;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
import org.mapstruct.ap.model.MethodReference;
|
|
||||||
import org.mapstruct.ap.model.common.ConversionContext;
|
import org.mapstruct.ap.model.common.ConversionContext;
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
@ -31,44 +29,28 @@ import org.mapstruct.ap.model.common.TypeFactory;
|
|||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public class XmlGregorianCalendarToString extends BuiltInMappingMethod {
|
public class XmlGregorianCalendarToString extends BuiltInMethod {
|
||||||
|
|
||||||
private static final Class SOURCE = XMLGregorianCalendar.class;
|
private final Parameter parameter;
|
||||||
private static final Class TARGET = String.class;
|
private final Type returnType;
|
||||||
|
|
||||||
private final TypeFactory typeFactory;
|
|
||||||
private ConversionContext conversionContext;
|
|
||||||
|
|
||||||
public XmlGregorianCalendarToString( TypeFactory typeFactory ) {
|
public XmlGregorianCalendarToString( TypeFactory typeFactory ) {
|
||||||
this.typeFactory = typeFactory;
|
this.parameter = typeFactory.createParameter( "xcal" , XMLGregorianCalendar.class );
|
||||||
|
this.returnType = typeFactory.getType( String.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodReference createMethodReference() {
|
public Parameter getParameter() {
|
||||||
return new MethodReference(
|
return parameter;
|
||||||
getName(),
|
|
||||||
asList( new Parameter[] { typeFactory.createParameter( "xcal" , SOURCE ) } ),
|
|
||||||
typeFactory.getType( TARGET ),
|
|
||||||
getContextParm()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type source() {
|
public Type getReturnType() {
|
||||||
return typeFactory.getType( SOURCE ).erasure();
|
return returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type target() {
|
public String getContextParameter(ConversionContext conversionContext) {
|
||||||
return typeFactory.getType( TARGET ).erasure();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setConversionContext(ConversionContext conversionContext) {
|
|
||||||
this.conversionContext = conversionContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getContextParm() {
|
|
||||||
return conversionContext.getDateFormat() != null ? "\"" + conversionContext.getDateFormat() + "\"" : "null";
|
return conversionContext.getDateFormat() != null ? "\"" + conversionContext.getDateFormat() + "\"" : "null";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,7 @@ public interface ConversionProvider {
|
|||||||
*
|
*
|
||||||
* @param sourceReference A reference to the source object, e.g.
|
* @param sourceReference A reference to the source object, e.g.
|
||||||
* {@code beanName.getFoo()}.
|
* {@code beanName.getFoo()}.
|
||||||
* @param conversionContext ConversionContext providing optional information required for creating
|
* @param conversionContext ConversionContext providing optional information required for creating the conversion.
|
||||||
the conversion.
|
|
||||||
*
|
*
|
||||||
* @return A conversion from source to target.
|
* @return A conversion from source to target.
|
||||||
*/
|
*/
|
||||||
@ -52,8 +51,7 @@ public interface ConversionProvider {
|
|||||||
*
|
*
|
||||||
* @param targetReference A reference to the targetReference object, e.g.
|
* @param targetReference A reference to the targetReference object, e.g.
|
||||||
* {@code beanName.getFoo()}.
|
* {@code beanName.getFoo()}.
|
||||||
* @param conversionContext ConversionContext providing optional information required for creating
|
* @param conversionContext ConversionContext providing optional information required for creating the conversion.
|
||||||
the conversion.
|
|
||||||
*
|
*
|
||||||
* @return A conversion from target to source.
|
* @return A conversion from target to source.
|
||||||
*/
|
*/
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2012-2014 Gunnar Morling (http://www.gunnarmorling.de/)
|
|
||||||
* and/or other contributors as indicated by the @authors tag. See the
|
|
||||||
* copyright.txt file in the distribution for a full listing of all
|
|
||||||
* contributors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT 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.model;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.mapstruct.ap.model.common.ConversionContext;
|
|
||||||
import org.mapstruct.ap.model.common.ModelElement;
|
|
||||||
import org.mapstruct.ap.model.common.Type;
|
|
||||||
import org.mapstruct.ap.util.Strings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementations create:
|
|
||||||
* 1) an implementation of this build in method.
|
|
||||||
* 2) a reference to a build in method, to use in property mappings
|
|
||||||
* 3) a name for logging purposes.
|
|
||||||
*
|
|
||||||
* @author Sjaak Derksen
|
|
||||||
*/
|
|
||||||
public abstract class BuiltInMappingMethod extends ModelElement {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a reference to the conversion method
|
|
||||||
*
|
|
||||||
* @return reference to method implementation
|
|
||||||
*/
|
|
||||||
public abstract MethodReference createMethodReference();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the conversion context which is used to add context information such as date / time
|
|
||||||
* conversion pattern, etc.
|
|
||||||
*
|
|
||||||
* @param conversionContext ConversionContext providing optional information required for creating
|
|
||||||
the conversion.
|
|
||||||
*/
|
|
||||||
public void setConversionContext(ConversionContext conversionContext) { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* hashCode
|
|
||||||
*
|
|
||||||
* @return hashCode
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return this.getClass().hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* equals based on class
|
|
||||||
*
|
|
||||||
* @param obj other class
|
|
||||||
* @return true when classes are the same
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean equals( Object obj ) {
|
|
||||||
if ( obj == null ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ( getClass() == obj.getClass() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tests whether generics do match. Default true.
|
|
||||||
*
|
|
||||||
* @param sourceType
|
|
||||||
* @param targetType
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean doGenericsMatch( Type sourceType, Type targetType ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* method name
|
|
||||||
* @return default method name is equal to class name of conversionmethod
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return Strings.decapitalize( this.getClass().getSimpleName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* imported types default. Only used types should be added. Source and Target types are coming via
|
|
||||||
* the MethodReference
|
|
||||||
*
|
|
||||||
* @return set of used types.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<Type> getImportTypes() {
|
|
||||||
return Collections.<Type>emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract Type source();
|
|
||||||
|
|
||||||
public abstract Type target();
|
|
||||||
}
|
|
@ -0,0 +1,166 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2014 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT 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.model;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.model.common.Accessibility;
|
||||||
|
import org.mapstruct.ap.model.common.ConversionContext;
|
||||||
|
import org.mapstruct.ap.model.common.ModelElement;
|
||||||
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
|
import org.mapstruct.ap.model.common.Type;
|
||||||
|
import org.mapstruct.ap.model.source.BasicMethod;
|
||||||
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementations create:
|
||||||
|
* 1) an implementation of this build in method.
|
||||||
|
* 2) a reference to a build in method, to use in property mappings
|
||||||
|
* 3) a name for logging purposes.
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public abstract class BuiltInMethod extends ModelElement implements BasicMethod {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method name
|
||||||
|
* @return default method name is equal to class name of build in mehtod
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return Strings.decapitalize( this.getClass().getSimpleName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* imported types default. Only used types should be added. Source and Target types are coming via
|
||||||
|
* the MethodReference
|
||||||
|
*
|
||||||
|
* @return set of used types.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<Type> getImportTypes() {
|
||||||
|
return Collections.<Type>emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches( Type sourceType, Type targetType ) {
|
||||||
|
if ( targetType.erasure().isAssignableTo( getReturnType().erasure() )
|
||||||
|
&& sourceType.erasure().isAssignableTo( getParameter().getType().erasure() ) ) {
|
||||||
|
return doTypeVarsMatch( sourceType, targetType );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return all parameters are source parameters for build-in methods.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Parameter> getSourceParameters() {
|
||||||
|
return getParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* declaring mapper is always null, being the MapperImpl
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Type getDeclaringMapper() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Parameter> getParameters() {
|
||||||
|
return Arrays.asList( new Parameter[] { getParameter() } );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* target parameter mechanism not supported for build-in-method
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Parameter getTargetParameter() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the conversion context is used to format an auxiliary parameter in the method call
|
||||||
|
* with context specific information such as a date format.
|
||||||
|
*
|
||||||
|
* @param conversionContext
|
||||||
|
* @return null if no context parameter should be included
|
||||||
|
* "null" if there should be an explicit null call
|
||||||
|
* "'dateFormat'" for instance, to indicate how the build-in method should format the date
|
||||||
|
*/
|
||||||
|
public String getContextParameter(ConversionContext conversionContext) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hashCode
|
||||||
|
*
|
||||||
|
* @return hashCode
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.getClass().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* equals based on class
|
||||||
|
*
|
||||||
|
* @param obj other class
|
||||||
|
* @return true when classes are the same
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals( Object obj ) {
|
||||||
|
if ( obj == null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ( getClass() == obj.getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes the Java Generics type variables in the parameter do match the type variables in the build in method
|
||||||
|
* same goes for the returnType.
|
||||||
|
*
|
||||||
|
* @param parameter source
|
||||||
|
* @param returnType target
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean doTypeVarsMatch( Type parameter, Type returnType ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There's currently only one parameter foreseen instead of a list of parameter
|
||||||
|
*
|
||||||
|
* @return the parameter
|
||||||
|
*/
|
||||||
|
public abstract Parameter getParameter();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Accessibility getAccessibility() {
|
||||||
|
return Accessibility.PRIVATE;
|
||||||
|
}
|
||||||
|
}
|
@ -53,14 +53,14 @@ public class Mapper extends ModelElement {
|
|||||||
private final List<Annotation> annotations;
|
private final List<Annotation> annotations;
|
||||||
private final List<MappingMethod> mappingMethods;
|
private final List<MappingMethod> mappingMethods;
|
||||||
private final List<MapperReference> referencedMappers;
|
private final List<MapperReference> referencedMappers;
|
||||||
private final Set<BuiltInMappingMethod> builtInMethods;
|
private final Set<BuiltInMethod> builtInMethods;
|
||||||
private final boolean suppressGeneratorTimestamp;
|
private final boolean suppressGeneratorTimestamp;
|
||||||
private final Accessibility accessibility;
|
private final Accessibility accessibility;
|
||||||
|
|
||||||
private Mapper(TypeFactory typeFactory, String packageName, boolean superTypeIsInterface, String interfaceName,
|
private Mapper(TypeFactory typeFactory, String packageName, boolean superTypeIsInterface, String interfaceName,
|
||||||
String implementationName, List<MappingMethod> mappingMethods,
|
String implementationName, List<MappingMethod> mappingMethods,
|
||||||
List<MapperReference> referencedMappers, boolean suppressGeneratorTimestamp,
|
List<MapperReference> referencedMappers, boolean suppressGeneratorTimestamp,
|
||||||
Set<BuiltInMappingMethod> builtInMethods, Accessibility accessibility) {
|
Set<BuiltInMethod> builtInMethods, Accessibility accessibility) {
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
this.superTypeIsInterface = superTypeIsInterface;
|
this.superTypeIsInterface = superTypeIsInterface;
|
||||||
this.interfaceName = interfaceName;
|
this.interfaceName = interfaceName;
|
||||||
@ -80,7 +80,7 @@ public class Mapper extends ModelElement {
|
|||||||
private TypeElement element;
|
private TypeElement element;
|
||||||
private List<MappingMethod> mappingMethods;
|
private List<MappingMethod> mappingMethods;
|
||||||
private List<MapperReference> mapperReferences;
|
private List<MapperReference> mapperReferences;
|
||||||
private Set<BuiltInMappingMethod> builtInMethods;
|
private Set<BuiltInMethod> builtInMethods;
|
||||||
|
|
||||||
private Elements elementUtils;
|
private Elements elementUtils;
|
||||||
private boolean suppressGeneratorTimestamp;
|
private boolean suppressGeneratorTimestamp;
|
||||||
@ -100,7 +100,7 @@ public class Mapper extends ModelElement {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder builtInMethods(Set<BuiltInMappingMethod> builtInMethods) {
|
public Builder builtInMethods(Set<BuiltInMethod> builtInMethods) {
|
||||||
this.builtInMethods = builtInMethods;
|
this.builtInMethods = builtInMethods;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ public class Mapper extends ModelElement {
|
|||||||
addWithDependents( importedTypes, annotation.getType() );
|
addWithDependents( importedTypes, annotation.getType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( BuiltInMappingMethod builtInMethod : builtInMethods ) {
|
for ( BuiltInMethod builtInMethod : builtInMethods ) {
|
||||||
for ( Type type : builtInMethod.getImportTypes() ) {
|
for ( Type type : builtInMethod.getImportTypes() ) {
|
||||||
addWithDependents( importedTypes, type );
|
addWithDependents( importedTypes, type );
|
||||||
}
|
}
|
||||||
@ -250,7 +250,7 @@ public class Mapper extends ModelElement {
|
|||||||
return accessibility;
|
return accessibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<BuiltInMappingMethod> getBuiltInMethods() {
|
public Set<BuiltInMethod> getBuiltInMethods() {
|
||||||
return builtInMethods;
|
return builtInMethods;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import org.mapstruct.ap.model.common.Accessibility;
|
|||||||
import org.mapstruct.ap.model.common.ModelElement;
|
import org.mapstruct.ap.model.common.ModelElement;
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.BasicMethod;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +43,7 @@ public abstract class MappingMethod extends ModelElement {
|
|||||||
private final Parameter targetParameter;
|
private final Parameter targetParameter;
|
||||||
private final Accessibility accessibility;
|
private final Accessibility accessibility;
|
||||||
|
|
||||||
protected MappingMethod(Method method) {
|
protected MappingMethod(BasicMethod method) {
|
||||||
this.name = method.getName();
|
this.name = method.getName();
|
||||||
this.parameters = method.getParameters();
|
this.parameters = method.getParameters();
|
||||||
this.returnType = method.getReturnType();
|
this.returnType = method.getReturnType();
|
||||||
|
@ -19,9 +19,8 @@
|
|||||||
package org.mapstruct.ap.model;
|
package org.mapstruct.ap.model;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.ConversionContext;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
@ -36,16 +35,17 @@ public class MethodReference extends MappingMethod {
|
|||||||
private final MapperReference declaringMapper;
|
private final MapperReference declaringMapper;
|
||||||
private final String contextParam;
|
private final String contextParam;
|
||||||
|
|
||||||
public MethodReference(Method method, MapperReference declaringMapper) {
|
|
||||||
|
public MethodReference(Method method, MapperReference declaringMapper ) {
|
||||||
super( method );
|
super( method );
|
||||||
this.declaringMapper = declaringMapper;
|
this.declaringMapper = declaringMapper;
|
||||||
this.contextParam = null;
|
this.contextParam = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference(String name, List<Parameter> parameters, Type returnType, String contextParam ) {
|
public MethodReference(BuiltInMethod method, ConversionContext contextParam ) {
|
||||||
super( name, parameters, returnType, null );
|
super( method );
|
||||||
this.contextParam = contextParam;
|
|
||||||
this.declaringMapper = null;
|
this.declaringMapper = null;
|
||||||
|
this.contextParam = method.getContextParameter( contextParam );
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapperReference getDeclaringMapper() {
|
public MapperReference getDeclaringMapper() {
|
||||||
@ -63,4 +63,11 @@ public class MethodReference extends MappingMethod {
|
|||||||
public String getContextParam() {
|
public String getContextParam() {
|
||||||
return contextParam;
|
return contextParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String quoteParamWhenNotNull(String param) {
|
||||||
|
if (param != null ) {
|
||||||
|
return param != null ? "\"" + param + "\"" : "null";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2014 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT 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.model.source;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.model.common.Accessibility;
|
||||||
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
|
import org.mapstruct.ap.model.common.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public interface BasicMethod {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sourceType
|
||||||
|
* @param targetType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean matches( Type sourceType, Type targetType );
|
||||||
|
|
||||||
|
List<Parameter> getSourceParameters();
|
||||||
|
|
||||||
|
Type getDeclaringMapper();
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
List<Parameter> getParameters();
|
||||||
|
|
||||||
|
Type getReturnType();
|
||||||
|
|
||||||
|
Parameter getTargetParameter();
|
||||||
|
|
||||||
|
Accessibility getAccessibility();
|
||||||
|
}
|
@ -22,8 +22,10 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
import javax.lang.model.util.Types;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.common.Accessibility;
|
import org.mapstruct.ap.model.common.Accessibility;
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
@ -40,7 +42,7 @@ import org.mapstruct.ap.util.Strings;
|
|||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
public class Method {
|
public class Method implements BasicMethod {
|
||||||
|
|
||||||
private final Type declaringMapper;
|
private final Type declaringMapper;
|
||||||
private final ExecutableElement executable;
|
private final ExecutableElement executable;
|
||||||
@ -48,6 +50,7 @@ public class Method {
|
|||||||
private final Parameter targetParameter;
|
private final Parameter targetParameter;
|
||||||
private final Type returnType;
|
private final Type returnType;
|
||||||
private final Accessibility accessibility;
|
private final Accessibility accessibility;
|
||||||
|
private final Types typeUtils;
|
||||||
|
|
||||||
private Map<String, List<Mapping>> mappings;
|
private Map<String, List<Mapping>> mappings;
|
||||||
private IterableMapping iterableMapping;
|
private IterableMapping iterableMapping;
|
||||||
@ -57,13 +60,22 @@ public class Method {
|
|||||||
|
|
||||||
public static Method forMethodRequiringImplementation(ExecutableElement executable, List<Parameter> parameters,
|
public static Method forMethodRequiringImplementation(ExecutableElement executable, List<Parameter> parameters,
|
||||||
Type returnType, Map<String, List<Mapping>> mappings,
|
Type returnType, Map<String, List<Mapping>> mappings,
|
||||||
IterableMapping iterableMapping, MapMapping mapMapping) {
|
IterableMapping iterableMapping, MapMapping mapMapping,
|
||||||
|
Types typeUtils ) {
|
||||||
|
|
||||||
return new Method( null, executable, parameters, returnType, mappings, iterableMapping, mapMapping );
|
return new Method(
|
||||||
|
null,
|
||||||
|
executable,
|
||||||
|
parameters,
|
||||||
|
returnType,
|
||||||
|
mappings,
|
||||||
|
iterableMapping,
|
||||||
|
mapMapping,
|
||||||
|
typeUtils );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method forReferencedMethod(Type declaringMapper, ExecutableElement executable,
|
public static Method forReferencedMethod(Type declaringMapper, ExecutableElement executable,
|
||||||
List<Parameter> parameters, Type returnType) {
|
List<Parameter> parameters, Type returnType, Types typeUtils ) {
|
||||||
|
|
||||||
return new Method(
|
return new Method(
|
||||||
declaringMapper,
|
declaringMapper,
|
||||||
@ -72,12 +84,13 @@ public class Method {
|
|||||||
returnType,
|
returnType,
|
||||||
Collections.<String, List<Mapping>>emptyMap(),
|
Collections.<String, List<Mapping>>emptyMap(),
|
||||||
null,
|
null,
|
||||||
null
|
null,
|
||||||
|
typeUtils
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method forFactoryMethod(Type declaringMapper, ExecutableElement executable,
|
public static Method forFactoryMethod(Type declaringMapper, ExecutableElement executable,
|
||||||
Type returnType) {
|
Type returnType, Types typeUtils) {
|
||||||
|
|
||||||
return new Method(
|
return new Method(
|
||||||
declaringMapper,
|
declaringMapper,
|
||||||
@ -86,12 +99,14 @@ public class Method {
|
|||||||
returnType,
|
returnType,
|
||||||
Collections.<String, List<Mapping>>emptyMap(),
|
Collections.<String, List<Mapping>>emptyMap(),
|
||||||
null,
|
null,
|
||||||
null
|
null,
|
||||||
|
typeUtils
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Method(Type declaringMapper, ExecutableElement executable, List<Parameter> parameters, Type returnType,
|
private Method(Type declaringMapper, ExecutableElement executable, List<Parameter> parameters, Type returnType,
|
||||||
Map<String, List<Mapping>> mappings, IterableMapping iterableMapping, MapMapping mapMapping) {
|
Map<String, List<Mapping>> mappings, IterableMapping iterableMapping, MapMapping mapMapping,
|
||||||
|
Types typeUtils ) {
|
||||||
this.declaringMapper = declaringMapper;
|
this.declaringMapper = declaringMapper;
|
||||||
this.executable = executable;
|
this.executable = executable;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
@ -102,6 +117,8 @@ public class Method {
|
|||||||
this.accessibility = Accessibility.fromModifiers( executable.getModifiers() );
|
this.accessibility = Accessibility.fromModifiers( executable.getModifiers() );
|
||||||
|
|
||||||
this.targetParameter = determineTargetParameter( parameters );
|
this.targetParameter = determineTargetParameter( parameters );
|
||||||
|
|
||||||
|
this.typeUtils = typeUtils;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Parameter determineTargetParameter(Iterable<Parameter> parameters) {
|
private Parameter determineTargetParameter(Iterable<Parameter> parameters) {
|
||||||
@ -120,6 +137,7 @@ public class Method {
|
|||||||
*
|
*
|
||||||
* @return The declaring mapper type
|
* @return The declaring mapper type
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Type getDeclaringMapper() {
|
public Type getDeclaringMapper() {
|
||||||
return declaringMapper;
|
return declaringMapper;
|
||||||
}
|
}
|
||||||
@ -128,14 +146,17 @@ public class Method {
|
|||||||
return executable;
|
return executable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return executable.getSimpleName().toString();
|
return executable.getSimpleName().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<Parameter> getParameters() {
|
public List<Parameter> getParameters() {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<Parameter> getSourceParameters() {
|
public List<Parameter> getSourceParameters() {
|
||||||
List<Parameter> sourceParameters = new ArrayList<Parameter>();
|
List<Parameter> sourceParameters = new ArrayList<Parameter>();
|
||||||
|
|
||||||
@ -162,6 +183,7 @@ public class Method {
|
|||||||
return targetParameter != null ? targetParameter.getType() : returnType;
|
return targetParameter != null ? targetParameter.getType() : returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Type getReturnType() {
|
public Type getReturnType() {
|
||||||
return returnType;
|
return returnType;
|
||||||
}
|
}
|
||||||
@ -203,6 +225,7 @@ public class Method {
|
|||||||
&& equals( getResultType(), method.getSourceParameters().iterator().next().getType() );
|
&& equals( getResultType(), method.getSourceParameters().iterator().next().getType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Parameter getTargetParameter() {
|
public Parameter getTargetParameter() {
|
||||||
return targetParameter;
|
return targetParameter;
|
||||||
}
|
}
|
||||||
@ -267,8 +290,23 @@ public class Method {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether an implementation of this method must be generated or not.
|
* Whether an implementation of this method must be generated or not.
|
||||||
|
*
|
||||||
|
* @return true when an implementation is required
|
||||||
*/
|
*/
|
||||||
public boolean requiresImplementation() {
|
public boolean requiresImplementation() {
|
||||||
return declaringMapper == null && executable.getModifiers().contains( Modifier.ABSTRACT );
|
return declaringMapper == null && executable.getModifiers().contains( Modifier.ABSTRACT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sourceType
|
||||||
|
* @param targetType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean matches( Type sourceType, Type targetType ) {
|
||||||
|
MethodMatcher matcher = new MethodMatcher(typeUtils, this );
|
||||||
|
return matcher.matches( sourceType, targetType );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,20 +61,31 @@ import org.mapstruct.ap.model.common.Type;
|
|||||||
*/
|
*/
|
||||||
public class MethodMatcher {
|
public class MethodMatcher {
|
||||||
|
|
||||||
private final Type parameter;
|
|
||||||
private final Type returnType;
|
|
||||||
private final Method candidateMethod;
|
private final Method candidateMethod;
|
||||||
private final Types typeUtils;
|
private final Types typeUtils;
|
||||||
private final Map<TypeVariable, TypeMirror> genericTypesMap = new HashMap<TypeVariable, TypeMirror>();
|
private final Map<TypeVariable, TypeMirror> genericTypesMap = new HashMap<TypeVariable, TypeMirror>();
|
||||||
|
|
||||||
public MethodMatcher(Types typeUtils, Method candidateMethod, Type returnType, Type parameter) {
|
/**
|
||||||
|
* package scope constructor
|
||||||
|
*
|
||||||
|
* @param typeUtils
|
||||||
|
* @param candidateMethod
|
||||||
|
*/
|
||||||
|
MethodMatcher(Types typeUtils, Method candidateMethod) {
|
||||||
this.typeUtils = typeUtils;
|
this.typeUtils = typeUtils;
|
||||||
this.candidateMethod = candidateMethod;
|
this.candidateMethod = candidateMethod;
|
||||||
this.parameter = parameter;
|
|
||||||
this.returnType = returnType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matches() {
|
/**
|
||||||
|
* package scoped method
|
||||||
|
*
|
||||||
|
* @param sourceType
|
||||||
|
* @param targetType
|
||||||
|
*
|
||||||
|
* @return true when both, sourceType and targetType matches the signature.
|
||||||
|
*/
|
||||||
|
boolean matches( Type sourceType, Type targetType ) {
|
||||||
// check & collect generic types.
|
// check & collect generic types.
|
||||||
List<? extends VariableElement> candidateParameters = candidateMethod.getExecutable().getParameters();
|
List<? extends VariableElement> candidateParameters = candidateMethod.getExecutable().getParameters();
|
||||||
|
|
||||||
@ -83,14 +94,14 @@ public class MethodMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TypeMatcher parameterMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_FROM );
|
TypeMatcher parameterMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_FROM );
|
||||||
if ( !parameterMatcher.visit( candidateParameters.iterator().next().asType(), parameter.getTypeMirror() ) ) {
|
if ( !parameterMatcher.visit( candidateParameters.iterator().next().asType(), sourceType.getTypeMirror() ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check return type
|
// check return type
|
||||||
TypeMirror candidateReturnType = candidateMethod.getExecutable().getReturnType();
|
TypeMirror candidateReturnType = candidateMethod.getExecutable().getReturnType();
|
||||||
TypeMatcher returnTypeMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_TO );
|
TypeMatcher returnTypeMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_TO );
|
||||||
if ( !returnTypeMatcher.visit( candidateReturnType, returnType.getTypeMirror() ) ) {
|
if ( !returnTypeMatcher.visit( candidateReturnType, targetType.getTypeMirror() ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ import org.mapstruct.ap.model.common.ConversionContext;
|
|||||||
import org.mapstruct.ap.conversion.ConversionProvider;
|
import org.mapstruct.ap.conversion.ConversionProvider;
|
||||||
import org.mapstruct.ap.conversion.Conversions;
|
import org.mapstruct.ap.conversion.Conversions;
|
||||||
import org.mapstruct.ap.model.common.DefaultConversionContext;
|
import org.mapstruct.ap.model.common.DefaultConversionContext;
|
||||||
import org.mapstruct.ap.model.BuiltInMappingMethod;
|
import org.mapstruct.ap.model.BuiltInMethod;
|
||||||
import org.mapstruct.ap.builtin.BuiltInMappingMethods;
|
import org.mapstruct.ap.builtin.BuiltInMappingMethods;
|
||||||
import org.mapstruct.ap.model.BeanMappingMethod;
|
import org.mapstruct.ap.model.BeanMappingMethod;
|
||||||
import org.mapstruct.ap.model.DefaultMapperReference;
|
import org.mapstruct.ap.model.DefaultMapperReference;
|
||||||
@ -56,9 +56,9 @@ import org.mapstruct.ap.model.TypeConversion;
|
|||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
|
import org.mapstruct.ap.model.source.BasicMethod;
|
||||||
import org.mapstruct.ap.model.source.Mapping;
|
import org.mapstruct.ap.model.source.Mapping;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
import org.mapstruct.ap.model.source.MethodMatcher;
|
|
||||||
import org.mapstruct.ap.option.Options;
|
import org.mapstruct.ap.option.Options;
|
||||||
import org.mapstruct.ap.option.ReportingPolicy;
|
import org.mapstruct.ap.option.ReportingPolicy;
|
||||||
import org.mapstruct.ap.prism.MapperPrism;
|
import org.mapstruct.ap.prism.MapperPrism;
|
||||||
@ -82,8 +82,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
private TypeFactory typeFactory;
|
private TypeFactory typeFactory;
|
||||||
private Conversions conversions;
|
private Conversions conversions;
|
||||||
private BuiltInMappingMethods builtInMethods;
|
private BuiltInMappingMethods builtInMethods;
|
||||||
|
private Set<BuiltInMethod> usedBuiltInMethods;
|
||||||
private Set<BuiltInMappingMethod> usedBuiltInMethods;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mapper process(ProcessorContext context, TypeElement mapperTypeElement, List<Method> sourceModel) {
|
public Mapper process(ProcessorContext context, TypeElement mapperTypeElement, List<Method> sourceModel) {
|
||||||
@ -95,11 +94,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
this.typeFactory = context.getTypeFactory();
|
this.typeFactory = context.getTypeFactory();
|
||||||
this.conversions = new Conversions( elementUtils, typeFactory );
|
this.conversions = new Conversions( elementUtils, typeFactory );
|
||||||
|
|
||||||
this.builtInMethods = new BuiltInMappingMethods(messager, typeFactory );
|
this.builtInMethods = new BuiltInMappingMethods( typeFactory );
|
||||||
this.usedBuiltInMethods = new HashSet<BuiltInMappingMethod>();
|
this.usedBuiltInMethods = new HashSet<BuiltInMethod>();
|
||||||
|
|
||||||
this.builtInMethods = new BuiltInMappingMethods(messager, typeFactory );
|
|
||||||
this.usedBuiltInMethods = new HashSet<BuiltInMappingMethod>();
|
|
||||||
|
|
||||||
return getMapper( mapperTypeElement, sourceModel );
|
return getMapper( mapperTypeElement, sourceModel );
|
||||||
}
|
}
|
||||||
@ -121,7 +117,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
.suppressGeneratorTimestamp( options.isSuppressGeneratorTimestamp() )
|
.suppressGeneratorTimestamp( options.isSuppressGeneratorTimestamp() )
|
||||||
.typeFactory( typeFactory )
|
.typeFactory( typeFactory )
|
||||||
.elementUtils( elementUtils )
|
.elementUtils( elementUtils )
|
||||||
.builtInMethods( new HashSet<BuiltInMappingMethod>( usedBuiltInMethods ) )
|
.builtInMethods( new HashSet<BuiltInMethod>( usedBuiltInMethods ) )
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
usedBuiltInMethods.clear();
|
usedBuiltInMethods.clear();
|
||||||
@ -129,7 +125,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the effective policy for reporting unmapped target properties. If
|
* Returns the effective policy for reporting unmapped getReturnType properties. If
|
||||||
* explicitly set via {@code Mapper}, this value will be returned. Otherwise
|
* explicitly set via {@code Mapper}, this value will be returned. Otherwise
|
||||||
* the value from the corresponding processor option will be returned. If
|
* the value from the corresponding processor option will be returned. If
|
||||||
* that is not set either, the default value from
|
* that is not set either, the default value from
|
||||||
@ -137,7 +133,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
*
|
*
|
||||||
* @param element The type declaring the generated mapper type
|
* @param element The type declaring the generated mapper type
|
||||||
*
|
*
|
||||||
* @return The effective policy for reporting unmapped target properties.
|
* @return The effective policy for reporting unmapped getReturnType properties.
|
||||||
*/
|
*/
|
||||||
private ReportingPolicy getEffectiveUnmappedTargetPolicy(TypeElement element) {
|
private ReportingPolicy getEffectiveUnmappedTargetPolicy(TypeElement element) {
|
||||||
MapperPrism mapperPrism = MapperPrism.getInstanceOn( element );
|
MapperPrism mapperPrism = MapperPrism.getInstanceOn( element );
|
||||||
@ -570,15 +566,20 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
targetType = typeFactory.getReturnType( targetAcessor );
|
targetType = typeFactory.getReturnType( targetAcessor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// first try the SourceMethods
|
||||||
|
String mappedElement = "property '" + Executables.getPropertyName( sourceAccessor ) + "'";
|
||||||
MethodReference propertyMappingMethod = getMappingMethodReference(
|
MethodReference propertyMappingMethod = getMappingMethodReference(
|
||||||
method,
|
getBestMatch( method, mappedElement, methods, sourceType, targetType ),
|
||||||
"property '" + Executables.getPropertyName( sourceAccessor ) + "'",
|
mapperReferences );
|
||||||
mapperReferences,
|
|
||||||
methods,
|
// then try BuiltInMethods
|
||||||
sourceType,
|
if ( propertyMappingMethod == null ) {
|
||||||
targetType,
|
propertyMappingMethod = getMappingMethodReference(
|
||||||
dateFormat
|
getBestMatch( method, mappedElement, builtInMethods, sourceType, targetType ),
|
||||||
);
|
targetType,
|
||||||
|
dateFormat );
|
||||||
|
}
|
||||||
|
|
||||||
TypeConversion conversion = getConversion(
|
TypeConversion conversion = getConversion(
|
||||||
sourceType,
|
sourceType,
|
||||||
targetType,
|
targetType,
|
||||||
@ -622,16 +623,19 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
MethodReference elementMappingMethod =
|
// first try the SourceMethods
|
||||||
getMappingMethodReference(
|
MethodReference elementMappingMethod = getMappingMethodReference(
|
||||||
method,
|
getBestMatch( method, "collection element", methods, sourceElementType, targetElementType ),
|
||||||
"collection element",
|
mapperReferences );
|
||||||
mapperReferences,
|
|
||||||
methods,
|
// then try BuiltInMethods
|
||||||
sourceElementType,
|
if ( elementMappingMethod == null ) {
|
||||||
targetElementType,
|
elementMappingMethod = getMappingMethodReference(
|
||||||
dateFormat
|
getBestMatch( method, "collection element", builtInMethods, sourceElementType,
|
||||||
);
|
targetElementType ),
|
||||||
|
targetElementType,
|
||||||
|
dateFormat );
|
||||||
|
}
|
||||||
|
|
||||||
if ( !sourceElementType.isAssignableTo( targetElementType ) && conversion == null &&
|
if ( !sourceElementType.isAssignableTo( targetElementType ) && conversion == null &&
|
||||||
elementMappingMethod == null ) {
|
elementMappingMethod == null ) {
|
||||||
@ -676,24 +680,30 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
"entry.getValue()"
|
"entry.getValue()"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// first try the SourceMethods
|
||||||
MethodReference keyMappingMethod = getMappingMethodReference(
|
MethodReference keyMappingMethod = getMappingMethodReference(
|
||||||
method,
|
getBestMatch( method, "map key", methods, sourceKeyType, targetKeyType ), mapperReferences );
|
||||||
"map key",
|
|
||||||
mapperReferences,
|
// then try BuiltInMethods
|
||||||
methods,
|
if ( keyMappingMethod == null ) {
|
||||||
sourceKeyType,
|
keyMappingMethod = getMappingMethodReference(
|
||||||
targetKeyType,
|
getBestMatch( method, "map key", builtInMethods, sourceKeyType, targetKeyType ),
|
||||||
keyDateFormat
|
targetKeyType,
|
||||||
);
|
keyDateFormat );
|
||||||
|
}
|
||||||
|
|
||||||
|
// first try the SourceMethods
|
||||||
MethodReference valueMappingMethod = getMappingMethodReference(
|
MethodReference valueMappingMethod = getMappingMethodReference(
|
||||||
method,
|
getBestMatch( method, "map value", methods, sourceValueType, targetValueType ),
|
||||||
"map value",
|
mapperReferences );
|
||||||
mapperReferences,
|
|
||||||
methods,
|
// then try BuiltInMethods
|
||||||
sourceValueType,
|
if ( valueMappingMethod == null ) {
|
||||||
targetValueType,
|
valueMappingMethod = getMappingMethodReference(
|
||||||
valueDateFormat
|
getBestMatch( method, "map value", builtInMethods, sourceValueType, targetValueType ),
|
||||||
);
|
targetValueType,
|
||||||
|
valueDateFormat );
|
||||||
|
}
|
||||||
|
|
||||||
if ( !sourceKeyType.isAssignableTo( targetKeyType ) && keyConversion == null && keyMappingMethod == null ) {
|
if ( !sourceKeyType.isAssignableTo( targetKeyType ) && keyConversion == null && keyMappingMethod == null ) {
|
||||||
messager.printMessage(
|
messager.printMessage(
|
||||||
@ -742,28 +752,26 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private MethodReference getMappingMethodReference(Method mappingMethod, String mappedElement,
|
private <T extends BasicMethod> T getBestMatch(Method mappingMethod, String mappedElement,
|
||||||
List<MapperReference> mapperReferences,
|
Iterable<T> methods, Type parameterType,
|
||||||
Iterable<Method> methods, Type parameterType,
|
Type returnType) {
|
||||||
Type returnType, String dateFormat) {
|
List<T> candidatesWithMathingTargetType = new ArrayList<T>();
|
||||||
List<Method> candidatesWithMathingTargetType = new ArrayList<Method>();
|
|
||||||
|
|
||||||
for ( Method method : methods ) {
|
for ( T method : methods ) {
|
||||||
if ( method.getSourceParameters().size() != 1 ) {
|
if ( method.getSourceParameters().size() != 1 ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodMatcher m = new MethodMatcher( typeUtils, method, returnType, parameterType );
|
if ( method.matches( parameterType, returnType ) ) {
|
||||||
if ( m.matches() ) {
|
|
||||||
candidatesWithMathingTargetType.add( method );
|
candidatesWithMathingTargetType.add( method );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Method> candidatesWithBestMatchingSourceType = new ArrayList<Method>();
|
List<T> candidatesWithBestMatchingSourceType = new ArrayList<T>();
|
||||||
int bestMatchingSourceTypeDistance = Integer.MAX_VALUE;
|
int bestMatchingSourceTypeDistance = Integer.MAX_VALUE;
|
||||||
|
|
||||||
// find the methods with the minimum distance regarding source parameter type
|
// find the methods with the minimum distance regarding getParameter getParameter type
|
||||||
for ( Method method : candidatesWithMathingTargetType ) {
|
for ( T method : candidatesWithMathingTargetType ) {
|
||||||
Parameter singleSourceParam = method.getSourceParameters().iterator().next();
|
Parameter singleSourceParam = method.getSourceParameters().iterator().next();
|
||||||
|
|
||||||
int sourceTypeDistance = parameterType.distanceTo( singleSourceParam.getType() );
|
int sourceTypeDistance = parameterType.distanceTo( singleSourceParam.getType() );
|
||||||
@ -776,7 +784,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// print a warning if we find more than one method with minimum source type distance
|
// print a warning if we find more than one method with minimum getParameter type distance
|
||||||
if ( candidatesWithBestMatchingSourceType.size() > 1 ) {
|
if ( candidatesWithBestMatchingSourceType.size() > 1 ) {
|
||||||
messager.printMessage(
|
messager.printMessage(
|
||||||
Kind.ERROR,
|
Kind.ERROR,
|
||||||
@ -791,32 +799,15 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( !candidatesWithBestMatchingSourceType.isEmpty() ) {
|
if ( !candidatesWithBestMatchingSourceType.isEmpty() ) {
|
||||||
Method method = candidatesWithBestMatchingSourceType.get( 0 );
|
return candidatesWithBestMatchingSourceType.get( 0 );
|
||||||
MapperReference mapperReference = null;
|
}
|
||||||
|
|
||||||
for ( MapperReference ref : mapperReferences ) {
|
|
||||||
if ( ref.getMapperType().equals( method.getDeclaringMapper() ) ) {
|
|
||||||
mapperReference = ref;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new MethodReference( method, mapperReference );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BuiltInMappingMethod builtInMehtod = builtInMethods.getConversion( parameterType, returnType );
|
|
||||||
if (builtInMehtod != null ) {
|
|
||||||
ConversionContext context =
|
|
||||||
new DefaultConversionContext( typeFactory, returnType, dateFormat );
|
|
||||||
builtInMehtod.setConversionContext( context );
|
|
||||||
usedBuiltInMethods.add( builtInMehtod );
|
|
||||||
return builtInMehtod.createMethodReference();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int addToCandidateListIfMinimal(List<Method> candidatesWithBestMathingType, int bestMatchingTypeDistance,
|
|
||||||
Method method, int currentTypeDistance) {
|
private <T extends BasicMethod> int addToCandidateListIfMinimal(List<T> candidatesWithBestMathingType,
|
||||||
|
int bestMatchingTypeDistance, T method, int currentTypeDistance) {
|
||||||
if ( currentTypeDistance == bestMatchingTypeDistance ) {
|
if ( currentTypeDistance == bestMatchingTypeDistance ) {
|
||||||
candidatesWithBestMathingType.add( method );
|
candidatesWithBestMathingType.add( method );
|
||||||
}
|
}
|
||||||
@ -829,6 +820,29 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
return bestMatchingTypeDistance;
|
return bestMatchingTypeDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MethodReference getMappingMethodReference( Method method, List<MapperReference> mapperReferences ) {
|
||||||
|
if ( method != null ) {
|
||||||
|
MapperReference mapperReference = null;
|
||||||
|
for ( MapperReference ref : mapperReferences ) {
|
||||||
|
if ( ref.getMapperType().equals( method.getDeclaringMapper() ) ) {
|
||||||
|
mapperReference = ref;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new MethodReference( method, mapperReference );
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MethodReference getMappingMethodReference( BuiltInMethod method, Type returnType, String dateFormat ) {
|
||||||
|
if ( method != null ) {
|
||||||
|
usedBuiltInMethods.add( method );
|
||||||
|
ConversionContext ctx = new DefaultConversionContext( typeFactory, returnType, dateFormat );
|
||||||
|
return new MethodReference( method, ctx );
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports an error if source the property can't be mapped from source to target. A mapping if possible if one of
|
* Reports an error if source the property can't be mapped from source to target. A mapping if possible if one of
|
||||||
* the following conditions is true:
|
* the following conditions is true:
|
||||||
@ -952,10 +966,10 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A getter could be an alternative target-accessor if a setter is not available, and the
|
* A getter could be an alternative getReturnType-accessor if a setter is not available, and the
|
||||||
* target is a collection.
|
getReturnType is a collection.
|
||||||
*
|
*
|
||||||
* Provided such a getter is initialized lazy by the target class, e.g. in generated JAXB beans.
|
* Provided such a getter is initialized lazy by the getReturnType class, e.g. in generated JAXB beans.
|
||||||
*
|
*
|
||||||
* @param elements
|
* @param elements
|
||||||
*
|
*
|
||||||
|
@ -46,6 +46,7 @@ import org.mapstruct.ap.prism.MappingsPrism;
|
|||||||
import org.mapstruct.ap.util.AnnotationProcessingException;
|
import org.mapstruct.ap.util.AnnotationProcessingException;
|
||||||
|
|
||||||
import static javax.lang.model.util.ElementFilter.methodsIn;
|
import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||||
|
import javax.lang.model.util.Types;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ModelElementProcessor} which retrieves a list of {@link Method}s
|
* A {@link ModelElementProcessor} which retrieves a list of {@link Method}s
|
||||||
@ -59,12 +60,13 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
|
|
||||||
private Messager messager;
|
private Messager messager;
|
||||||
private TypeFactory typeFactory;
|
private TypeFactory typeFactory;
|
||||||
|
private Types typeUtils;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Method> process(ProcessorContext context, TypeElement mapperTypeElement, Void sourceModel) {
|
public List<Method> process(ProcessorContext context, TypeElement mapperTypeElement, Void sourceModel) {
|
||||||
this.messager = context.getMessager();
|
this.messager = context.getMessager();
|
||||||
this.typeFactory = context.getTypeFactory();
|
this.typeFactory = context.getTypeFactory();
|
||||||
|
this.typeUtils = context.getTypeUtils();
|
||||||
return retrieveMethods( mapperTypeElement, true );
|
return retrieveMethods( mapperTypeElement, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +140,8 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
returnType,
|
returnType,
|
||||||
getMappings( method ),
|
getMappings( method ),
|
||||||
IterableMapping.fromPrism( IterableMappingPrism.getInstanceOn( method ) ),
|
IterableMapping.fromPrism( IterableMappingPrism.getInstanceOn( method ) ),
|
||||||
MapMapping.fromPrism( MapMappingPrism.getInstanceOn( method ) )
|
MapMapping.fromPrism( MapMappingPrism.getInstanceOn( method ) ),
|
||||||
|
typeUtils
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -152,7 +155,8 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
mapperRequiresImplementation ? null : typeFactory.getType( element ),
|
mapperRequiresImplementation ? null : typeFactory.getType( element ),
|
||||||
method,
|
method,
|
||||||
parameters,
|
parameters,
|
||||||
returnType
|
returnType,
|
||||||
|
typeUtils
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//create factory method
|
//create factory method
|
||||||
@ -161,7 +165,8 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
Method.forFactoryMethod(
|
Method.forFactoryMethod(
|
||||||
mapperRequiresImplementation ? null : typeFactory.getType( element ),
|
mapperRequiresImplementation ? null : typeFactory.getType( element ),
|
||||||
method,
|
method,
|
||||||
returnType
|
returnType,
|
||||||
|
typeUtils
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user