mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#92 The getter methods and setter methods contain pure getters and setters. A new method has been created to offer an alternative target accessors for Collection properties when setter is not available. The lists for this are kept separate.
This commit is contained in:
parent
e5cfb07af5
commit
6c2683a6f3
@ -53,7 +53,6 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
|
||||
private final boolean isEnumType;
|
||||
private final boolean isIterableType;
|
||||
private final boolean isCollectionType;
|
||||
private final boolean isListType;
|
||||
private final boolean isMapType;
|
||||
private final Type implementationType;
|
||||
private final TypeMirror typeMirror;
|
||||
@ -61,14 +60,13 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
|
||||
private final TypeElement typeElement;
|
||||
|
||||
public Type(TypeMirror typeMirror, List<Type> typeParameters, Type implementationType, boolean isIterableType,
|
||||
boolean isCollectionType, boolean isListType, boolean isMapType, Types typeUtils,
|
||||
boolean isCollectionType, boolean isMapType, Types typeUtils,
|
||||
Elements elementUtils) {
|
||||
this.typeMirror = typeMirror;
|
||||
this.implementationType = implementationType;
|
||||
this.typeParameters = typeParameters;
|
||||
this.isIterableType = isIterableType;
|
||||
this.isCollectionType = isCollectionType;
|
||||
this.isListType = isListType;
|
||||
this.isMapType = isMapType;
|
||||
this.typeUtils = typeUtils;
|
||||
|
||||
@ -152,10 +150,6 @@ public class Type extends AbstractModelElement implements Comparable<Type> {
|
||||
return isCollectionType;
|
||||
}
|
||||
|
||||
public boolean isListType() {
|
||||
return isListType;
|
||||
}
|
||||
|
||||
public boolean isMapType() {
|
||||
return isMapType;
|
||||
}
|
||||
|
@ -284,19 +284,22 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
}
|
||||
|
||||
TypeElement resultTypeElement = method.getResultType().getTypeElement();
|
||||
List<ExecutableElement> targetSetters = filters.setterMethodsIn(
|
||||
List<ExecutableElement> targetAccessors = filters.setterMethodsIn(
|
||||
elementUtils.getAllMembers( resultTypeElement )
|
||||
);
|
||||
targetAccessors.addAll( filters.alternativeTargetAccessorMethodsIn(
|
||||
elementUtils.getAllMembers( resultTypeElement ) )
|
||||
);
|
||||
|
||||
for ( ExecutableElement setterMethod : targetSetters ) {
|
||||
String targetPropertyName = executables.getPropertyName( setterMethod );
|
||||
for ( ExecutableElement targetAccessor : targetAccessors ) {
|
||||
String targetPropertyName = executables.getPropertyName( targetAccessor );
|
||||
|
||||
Mapping mapping = method.getMapping( targetPropertyName );
|
||||
|
||||
PropertyMapping propertyMapping = null;
|
||||
if ( mapping != null && mapping.getSourceParameterName() != null ) {
|
||||
Parameter parameter = method.getSourceParameter( mapping.getSourceParameterName() );
|
||||
propertyMapping = getPropertyMapping( methods, method, setterMethod, parameter );
|
||||
propertyMapping = getPropertyMapping( methods, method, targetAccessor, parameter );
|
||||
}
|
||||
|
||||
if ( propertyMapping == null ) {
|
||||
@ -304,7 +307,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
PropertyMapping newPropertyMapping = getPropertyMapping(
|
||||
methods,
|
||||
method,
|
||||
setterMethod,
|
||||
targetAccessor,
|
||||
sourceParameter
|
||||
);
|
||||
if ( propertyMapping != null && newPropertyMapping != null ) {
|
||||
@ -327,7 +330,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> targetProperties = executables.getPropertyNames( targetSetters );
|
||||
Set<String> targetProperties = executables.getPropertyNames( targetAccessors );
|
||||
|
||||
reportErrorForUnmappedTargetPropertiesIfRequired(
|
||||
method,
|
||||
@ -380,20 +383,24 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Metho
|
||||
|
||||
private boolean hasProperty(Parameter parameter, String propertyName) {
|
||||
TypeElement parameterTypeElement = parameter.getType().getTypeElement();
|
||||
List<ExecutableElement> getters = filters.setterMethodsIn(
|
||||
List<ExecutableElement> targetAccessors = filters.setterMethodsIn(
|
||||
elementUtils.getAllMembers( parameterTypeElement )
|
||||
);
|
||||
|
||||
return executables.getPropertyNames( getters ).contains( propertyName );
|
||||
targetAccessors.addAll( filters.alternativeTargetAccessorMethodsIn(
|
||||
elementUtils.getAllMembers( parameterTypeElement ) )
|
||||
);
|
||||
return executables.getPropertyNames( targetAccessors ).contains( propertyName );
|
||||
}
|
||||
|
||||
private boolean reportErrorIfMappedPropertiesDontExist(Method method) {
|
||||
TypeElement resultTypeElement = method.getResultType().getTypeElement();
|
||||
List<ExecutableElement> targetSetters = filters.setterMethodsIn(
|
||||
List<ExecutableElement> targetAccessors = filters.setterMethodsIn(
|
||||
elementUtils.getAllMembers( resultTypeElement )
|
||||
);
|
||||
|
||||
Set<String> targetProperties = executables.getPropertyNames( targetSetters );
|
||||
targetAccessors.addAll( filters.alternativeTargetAccessorMethodsIn(
|
||||
elementUtils.getAllMembers( resultTypeElement ) )
|
||||
);
|
||||
Set<String> targetProperties = executables.getPropertyNames( targetAccessors );
|
||||
|
||||
boolean foundUnmappedProperty = false;
|
||||
|
||||
|
@ -52,16 +52,28 @@ public class Filters {
|
||||
|
||||
public List<ExecutableElement> setterMethodsIn(Iterable<? extends Element> elements) {
|
||||
List<ExecutableElement> setterMethods = new LinkedList<ExecutableElement>();
|
||||
List<ExecutableElement> getterMethods = new LinkedList<ExecutableElement>();
|
||||
|
||||
for ( ExecutableElement method : methodsIn( elements ) ) {
|
||||
if ( executables.isSetterMethod( method ) ) {
|
||||
setterMethods.add( method );
|
||||
}
|
||||
else if ( executables.isGetterMethod( method ) ) {
|
||||
getterMethods.add( method );
|
||||
}
|
||||
}
|
||||
return setterMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* A getter could be an alternative target-accessor if a setter is not available, and the
|
||||
* target is a collection.
|
||||
*
|
||||
* Provided such a getter is initialized lazy by the target class, e.g. in generated JAXB beans.
|
||||
*
|
||||
* @param elements
|
||||
* @return
|
||||
*/
|
||||
public List<ExecutableElement> alternativeTargetAccessorMethodsIn(Iterable<? extends Element> elements) {
|
||||
List<ExecutableElement> setterMethods = setterMethodsIn( elements );
|
||||
List<ExecutableElement> getterMethods = getterMethodsIn( elements );
|
||||
List<ExecutableElement> alternativeTargetAccessorsMethods = new LinkedList<ExecutableElement>();
|
||||
|
||||
if (getterMethods.size() > setterMethods.size()) {
|
||||
// there could be a getter method for a list that is not present as setter.
|
||||
@ -77,12 +89,12 @@ public class Filters {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !matchFound && executables.retrieveReturnType( getterMethod ).isListType() ) {
|
||||
setterMethods.add( getterMethod );
|
||||
if ( !matchFound && executables.retrieveReturnType( getterMethod ).isCollectionType() ) {
|
||||
alternativeTargetAccessorsMethods.add( getterMethod );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return setterMethods;
|
||||
return alternativeTargetAccessorsMethods;
|
||||
}
|
||||
}
|
||||
|
@ -117,10 +117,6 @@ public class TypeFactory {
|
||||
mirror,
|
||||
collectionType
|
||||
);
|
||||
boolean isListType = typeUtils.isSubtype(
|
||||
mirror,
|
||||
listType
|
||||
);
|
||||
boolean isMapType = typeUtils.isSubtype(
|
||||
mirror,
|
||||
mapType
|
||||
@ -132,7 +128,6 @@ public class TypeFactory {
|
||||
implementationType,
|
||||
isIterableType,
|
||||
isCollectionType,
|
||||
isListType,
|
||||
isMapType,
|
||||
typeUtils,
|
||||
elementUtils
|
||||
@ -188,7 +183,6 @@ public class TypeFactory {
|
||||
null,
|
||||
implementationType.isIterableType(),
|
||||
implementationType.isCollectionType(),
|
||||
implementationType.isListType(),
|
||||
implementationType.isMapType(),
|
||||
typeUtils,
|
||||
elementUtils
|
||||
|
@ -71,7 +71,7 @@ public class CollectionMappingTest extends MapperTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IssueKey("6")
|
||||
@IssueKey("92")
|
||||
public void shouldMapListWithoutSetter() {
|
||||
Source source = new Source();
|
||||
source.setStringList2( Arrays.asList( "Bob", "Alice" ) );
|
||||
|
@ -171,7 +171,7 @@ public class DefaultCollectionImplementationTest extends MapperTestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IssueKey("6")
|
||||
@IssueKey("92")
|
||||
public void shouldUseDefaultImplementationForListWithoutSetter() {
|
||||
Source source = new Source();
|
||||
source.setFooList( createSourceFooList() );
|
||||
|
Loading…
x
Reference in New Issue
Block a user