mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#108 Aligning Array and Itterable mapping. Added ArrayCopyWrapper.
This commit is contained in:
parent
44509a158e
commit
08cf60e46a
@ -155,8 +155,14 @@ public abstract class GeneratedType extends ModelElement {
|
|||||||
typeToAdd.getPackageName() != null &&
|
typeToAdd.getPackageName() != null &&
|
||||||
!typeToAdd.getPackageName().equals( packageName ) &&
|
!typeToAdd.getPackageName().equals( packageName ) &&
|
||||||
!typeToAdd.getPackageName().startsWith( "java.lang" ) ) {
|
!typeToAdd.getPackageName().startsWith( "java.lang" ) ) {
|
||||||
|
|
||||||
|
if ( typeToAdd.isArrayType() ) {
|
||||||
|
collection.add( typeToAdd.getComponentType() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
collection.add( typeToAdd );
|
collection.add( typeToAdd );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addWithDependents( collection, typeToAdd.getImplementationType() );
|
addWithDependents( collection, typeToAdd.getImplementationType() );
|
||||||
|
|
||||||
|
@ -20,10 +20,12 @@ package org.mapstruct.ap.model;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import javax.lang.model.type.TypeKind;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.assignment.Assignment;
|
import org.mapstruct.ap.model.assignment.Assignment;
|
||||||
|
import org.mapstruct.ap.model.assignment.LocalVarWrapper;
|
||||||
import org.mapstruct.ap.model.assignment.SetterWrapper;
|
import org.mapstruct.ap.model.assignment.SetterWrapper;
|
||||||
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;
|
||||||
@ -74,13 +76,21 @@ public class IterableMappingMethod extends MappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IterableMappingMethod build() {
|
public IterableMappingMethod build() {
|
||||||
Type sourceElementType =
|
Type sourceParameterType = method.getSourceParameters().iterator().next().getType();
|
||||||
method.getSourceParameters().iterator().next().getType().getTypeParameters().get( 0 );
|
Type resultType = method.getResultType();
|
||||||
Type targetElementType =
|
|
||||||
method.getResultType().getTypeParameters().get( 0 );
|
|
||||||
String loopVariableName =
|
|
||||||
Strings.getSaveVariableName( sourceElementType.getName(), method.getParameterNames() );
|
|
||||||
|
|
||||||
|
Type sourceElementType = sourceParameterType.isArrayType() ? sourceParameterType.getComponentType() :
|
||||||
|
sourceParameterType.getTypeParameters().get( 0 );
|
||||||
|
Type targetElementType = resultType.isArrayType() ? resultType.getComponentType() :
|
||||||
|
resultType.getTypeParameters().get( 0 );
|
||||||
|
|
||||||
|
|
||||||
|
String elementTypeName = sourceParameterType.isArrayType() ?
|
||||||
|
sourceParameterType.getComponentType().getName() :
|
||||||
|
sourceParameterType.getTypeParameters().get( 0 ).getName();
|
||||||
|
|
||||||
|
String loopVariableName =
|
||||||
|
Strings.getSaveVariableName( elementTypeName, method.getParameterNames() );
|
||||||
|
|
||||||
Assignment assignment = ctx.getMappingResolver().getTargetAssignment(
|
Assignment assignment = ctx.getMappingResolver().getTargetAssignment(
|
||||||
method,
|
method,
|
||||||
@ -103,21 +113,25 @@ public class IterableMappingMethod extends MappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// target accessor is setter, so decorate assignment as setter
|
// target accessor is setter, so decorate assignment as setter
|
||||||
|
if ( resultType.isArrayType() ) {
|
||||||
|
assignment = new LocalVarWrapper( assignment, method.getThrownTypes() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
|
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
|
||||||
|
}
|
||||||
// mapNullToDefault
|
// mapNullToDefault
|
||||||
NullValueMappingPrism prism = NullValueMappingPrism.getInstanceOn( method.getExecutable() );
|
NullValueMappingPrism prism = NullValueMappingPrism.getInstanceOn( method.getExecutable() );
|
||||||
boolean mapNullToDefault
|
boolean mapNullToDefault
|
||||||
= MapperConfig.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
|
= MapperConfig.getInstanceOn( ctx.getMapperTypeElement() ).isMapToDefault( prism );
|
||||||
|
|
||||||
MethodReference factoryMethod = AssignmentFactory.createFactoryMethod( method.getReturnType(), ctx );
|
MethodReference factoryMethod = AssignmentFactory.createFactoryMethod( method.getReturnType(), ctx );
|
||||||
|
|
||||||
return new IterableMappingMethod(
|
return new IterableMappingMethod(
|
||||||
method,
|
method,
|
||||||
assignment,
|
assignment,
|
||||||
factoryMethod,
|
factoryMethod,
|
||||||
mapNullToDefault,
|
mapNullToDefault,
|
||||||
loopVariableName
|
loopVariableName );
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +163,6 @@ public class IterableMappingMethod extends MappingMethod {
|
|||||||
@Override
|
@Override
|
||||||
public Set<Type> getImportTypes() {
|
public Set<Type> getImportTypes() {
|
||||||
Set<Type> types = super.getImportTypes();
|
Set<Type> types = super.getImportTypes();
|
||||||
|
|
||||||
if ( elementAssignment != null ) {
|
if ( elementAssignment != null ) {
|
||||||
types.addAll( elementAssignment.getImportTypes() );
|
types.addAll( elementAssignment.getImportTypes() );
|
||||||
}
|
}
|
||||||
@ -169,10 +182,59 @@ public class IterableMappingMethod extends MappingMethod {
|
|||||||
return loopVariableName;
|
return loopVariableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDefaultValue() {
|
||||||
|
TypeKind kind = getResultElementType().getTypeMirror().getKind();
|
||||||
|
switch ( kind ) {
|
||||||
|
case BOOLEAN:
|
||||||
|
return "false";
|
||||||
|
case BYTE:
|
||||||
|
case SHORT:
|
||||||
|
case INT:
|
||||||
|
case CHAR: /*"'\u0000'" would have been better, but depends on platformencoding */
|
||||||
|
return "0";
|
||||||
|
case LONG:
|
||||||
|
return "0L";
|
||||||
|
case FLOAT:
|
||||||
|
return "0.0f";
|
||||||
|
case DOUBLE:
|
||||||
|
return "0.0d";
|
||||||
|
default:
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public MethodReference getFactoryMethod() {
|
public MethodReference getFactoryMethod() {
|
||||||
return this.factoryMethod;
|
return this.factoryMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getSourceElementType() {
|
||||||
|
Type sourceParameterType = getSourceParameter().getType();
|
||||||
|
|
||||||
|
if ( sourceParameterType.isArrayType() ) {
|
||||||
|
return sourceParameterType.getComponentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return sourceParameterType.getTypeParameters().get( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getResultElementType() {
|
||||||
|
if ( getResultType().isArrayType() ) {
|
||||||
|
return getResultType().getComponentType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getResultType().getTypeParameters().get( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIndex1Name() {
|
||||||
|
return Strings.getSaveVariableName( "i", loopVariableName, getSourceParameter().getName(), getResultName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIndex2Name() {
|
||||||
|
return Strings.getSaveVariableName( "j", loopVariableName, getSourceParameter().getName(), getResultName() );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
@ -28,7 +28,8 @@ 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.Method;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import static org.mapstruct.ap.util.Strings.getSaveVariableName;
|
||||||
|
import static org.mapstruct.ap.util.Strings.join;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A method implemented or referenced by a {@link Mapper} class.
|
* A method implemented or referenced by a {@link Mapper} class.
|
||||||
@ -78,8 +79,15 @@ public abstract class MappingMethod extends ModelElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getResultName() {
|
public String getResultName() {
|
||||||
return targetParameter != null ? targetParameter.getName() :
|
if ( targetParameter != null ) {
|
||||||
Strings.getSaveVariableName( getResultType().getName(), getParameterNames() );
|
return targetParameter.getName();
|
||||||
|
}
|
||||||
|
else if ( getResultType().isArrayType() ) {
|
||||||
|
return getSaveVariableName( getResultType().getComponentType().getName() + "Tmp", getParameterNames() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getSaveVariableName( getResultType().getName(), getParameterNames() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getReturnType() {
|
public Type getReturnType() {
|
||||||
@ -124,6 +132,6 @@ public abstract class MappingMethod extends ModelElement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return returnType + " " + getName() + "(" + Strings.join( parameters, ", " ) + ")";
|
return returnType + " " + getName() + "(" + join( parameters, ", " ) + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.model;
|
package org.mapstruct.ap.model;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
@ -25,6 +26,7 @@ import javax.lang.model.type.TypeMirror;
|
|||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.assignment.AdderWrapper;
|
import org.mapstruct.ap.model.assignment.AdderWrapper;
|
||||||
|
import org.mapstruct.ap.model.assignment.ArrayCopyWrapper;
|
||||||
import org.mapstruct.ap.model.assignment.Assignment;
|
import org.mapstruct.ap.model.assignment.Assignment;
|
||||||
import org.mapstruct.ap.model.assignment.GetterCollectionOrMapWrapper;
|
import org.mapstruct.ap.model.assignment.GetterCollectionOrMapWrapper;
|
||||||
import org.mapstruct.ap.model.assignment.NewCollectionOrMapWrapper;
|
import org.mapstruct.ap.model.assignment.NewCollectionOrMapWrapper;
|
||||||
@ -153,6 +155,11 @@ public class PropertyMapping extends ModelElement {
|
|||||||
if ( targetType.isCollectionOrMapType() ) {
|
if ( targetType.isCollectionOrMapType() ) {
|
||||||
assignment = assignCollection( targetType, targetAccessorType, assignment );
|
assignment = assignCollection( targetType, targetAccessorType, assignment );
|
||||||
}
|
}
|
||||||
|
else if ( targetType.isArrayType() && sourceType.isArrayType() && assignment.getType() == DIRECT ) {
|
||||||
|
Type arrayType = ctx.getTypeFactory().getType( Arrays.class );
|
||||||
|
assignment = new ArrayCopyWrapper( assignment, targetPropertyName, arrayType, targetType );
|
||||||
|
assignment = new NullCheckWrapper( assignment );
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
assignment = assignObject( sourceType, targetType, targetAccessorType, assignment );
|
assignment = assignObject( sourceType, targetType, targetAccessorType, assignment );
|
||||||
}
|
}
|
||||||
@ -367,7 +374,8 @@ public class PropertyMapping extends ModelElement {
|
|||||||
ExecutableElement element) {
|
ExecutableElement element) {
|
||||||
|
|
||||||
Assignment assignment = null;
|
Assignment assignment = null;
|
||||||
if ( sourceType.isCollectionType() && targetType.isCollectionType() ) {
|
if ( ( sourceType.isCollectionType() || sourceType.isArrayType() )
|
||||||
|
&& ( targetType.isCollectionType() || targetType.isArrayType() ) ) {
|
||||||
|
|
||||||
ForgedMethod methodToGenerate = new ForgedMethod( sourceType, targetType, element );
|
ForgedMethod methodToGenerate = new ForgedMethod( sourceType, targetType, element );
|
||||||
IterableMappingMethod.Builder builder = new IterableMappingMethod.Builder();
|
IterableMappingMethod.Builder builder = new IterableMappingMethod.Builder();
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* 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.assignment;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.model.common.Type;
|
||||||
|
import static org.mapstruct.ap.util.Strings.decapitalize;
|
||||||
|
import static org.mapstruct.ap.util.Strings.getSaveVariableName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorates the assignment as a Map or Collection constructor
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class ArrayCopyWrapper extends AssignmentWrapper {
|
||||||
|
|
||||||
|
private final String targetPropertyName;
|
||||||
|
private final Type arraysType;
|
||||||
|
private final Type targetType;
|
||||||
|
|
||||||
|
public ArrayCopyWrapper(Assignment decoratedAssignment, String targetPropertyName, Type arraysType,
|
||||||
|
Type targetType) {
|
||||||
|
super( decoratedAssignment );
|
||||||
|
this.targetPropertyName = targetPropertyName;
|
||||||
|
this.arraysType = arraysType;
|
||||||
|
this.targetType = targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Type> getImportTypes() {
|
||||||
|
Set<Type> imported = new HashSet<Type>();
|
||||||
|
imported.addAll( getAssignment().getImportTypes() );
|
||||||
|
imported.add( arraysType );
|
||||||
|
imported.add( targetType );
|
||||||
|
return imported;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalVarName() {
|
||||||
|
return getSaveVariableName( decapitalize( targetPropertyName ), Collections.<String>emptyList() );
|
||||||
|
}
|
||||||
|
}
|
@ -62,6 +62,7 @@ public class Type extends ModelElement implements Comparable<Type> {
|
|||||||
private final List<Type> typeParameters;
|
private final List<Type> typeParameters;
|
||||||
|
|
||||||
private final Type implementationType;
|
private final Type implementationType;
|
||||||
|
private final Type componentType;
|
||||||
|
|
||||||
private final String packageName;
|
private final String packageName;
|
||||||
private final String name;
|
private final String name;
|
||||||
@ -85,7 +86,7 @@ public class Type extends ModelElement implements Comparable<Type> {
|
|||||||
|
|
||||||
//CHECKSTYLE:OFF
|
//CHECKSTYLE:OFF
|
||||||
public Type(Types typeUtils, Elements elementUtils, TypeMirror typeMirror, TypeElement typeElement,
|
public Type(Types typeUtils, Elements elementUtils, TypeMirror typeMirror, TypeElement typeElement,
|
||||||
List<Type> typeParameters, Type implementationType, String packageName, String name,
|
List<Type> typeParameters, Type implementationType, Type componentType, String packageName, String name,
|
||||||
String qualifiedName, boolean isInterface, boolean isEnumType, boolean isIterableType,
|
String qualifiedName, boolean isInterface, boolean isEnumType, boolean isIterableType,
|
||||||
boolean isCollectionType, boolean isMapType, boolean isImported) {
|
boolean isCollectionType, boolean isMapType, boolean isImported) {
|
||||||
|
|
||||||
@ -95,6 +96,7 @@ public class Type extends ModelElement implements Comparable<Type> {
|
|||||||
this.typeMirror = typeMirror;
|
this.typeMirror = typeMirror;
|
||||||
this.typeElement = typeElement;
|
this.typeElement = typeElement;
|
||||||
this.typeParameters = typeParameters;
|
this.typeParameters = typeParameters;
|
||||||
|
this.componentType = componentType;
|
||||||
this.implementationType = implementationType;
|
this.implementationType = implementationType;
|
||||||
|
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
@ -147,6 +149,10 @@ public class Type extends ModelElement implements Comparable<Type> {
|
|||||||
return typeParameters;
|
return typeParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getComponentType() {
|
||||||
|
return componentType;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPrimitive() {
|
public boolean isPrimitive() {
|
||||||
return typeMirror.getKind().isPrimitive();
|
return typeMirror.getKind().isPrimitive();
|
||||||
}
|
}
|
||||||
@ -182,8 +188,13 @@ public class Type extends ModelElement implements Comparable<Type> {
|
|||||||
return implementationType;
|
return implementationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this type is a sub-type of {@link Iterable} or an array type.
|
||||||
|
*
|
||||||
|
* @return {@code true} if this type is a sub-type of {@link Iterable} or an array type, {@code false} otherwise.
|
||||||
|
*/
|
||||||
public boolean isIterableType() {
|
public boolean isIterableType() {
|
||||||
return isIterableType;
|
return isIterableType || isArrayType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCollectionType() {
|
public boolean isCollectionType() {
|
||||||
@ -198,13 +209,32 @@ public class Type extends ModelElement implements Comparable<Type> {
|
|||||||
return isCollectionType || isMapType;
|
return isCollectionType || isMapType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isArrayType() {
|
||||||
|
return componentType != null;
|
||||||
|
}
|
||||||
|
|
||||||
public String getFullyQualifiedName() {
|
public String getFullyQualifiedName() {
|
||||||
return qualifiedName;
|
return qualifiedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of this type as to be used within import statements.
|
||||||
|
*/
|
||||||
|
public String getImportName() {
|
||||||
|
return isArrayType() ? qualifiedName.substring( 0, qualifiedName.length() - 2 ) : qualifiedName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Type> getImportTypes() {
|
public Set<Type> getImportTypes() {
|
||||||
return implementationType != null ? Collections.singleton( implementationType ) : Collections.<Type>emptySet();
|
if ( implementationType != null ) {
|
||||||
|
return Collections.singleton( implementationType );
|
||||||
|
}
|
||||||
|
else if ( componentType != null ) {
|
||||||
|
return Collections.singleton( componentType );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Collections.<Type>emptySet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,6 +274,7 @@ public class Type extends ModelElement implements Comparable<Type> {
|
|||||||
typeElement,
|
typeElement,
|
||||||
typeParameters,
|
typeParameters,
|
||||||
implementationType,
|
implementationType,
|
||||||
|
componentType,
|
||||||
packageName,
|
packageName,
|
||||||
name,
|
name,
|
||||||
qualifiedName,
|
qualifiedName,
|
||||||
|
@ -43,6 +43,7 @@ import javax.lang.model.element.ElementKind;
|
|||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.element.VariableElement;
|
import javax.lang.model.element.VariableElement;
|
||||||
|
import javax.lang.model.type.ArrayType;
|
||||||
import javax.lang.model.type.DeclaredType;
|
import javax.lang.model.type.DeclaredType;
|
||||||
import javax.lang.model.type.ExecutableType;
|
import javax.lang.model.type.ExecutableType;
|
||||||
import javax.lang.model.type.PrimitiveType;
|
import javax.lang.model.type.PrimitiveType;
|
||||||
@ -134,12 +135,14 @@ public class TypeFactory {
|
|||||||
boolean isInterface;
|
boolean isInterface;
|
||||||
String name;
|
String name;
|
||||||
String packageName;
|
String packageName;
|
||||||
TypeElement typeElement;
|
|
||||||
String qualifiedName;
|
String qualifiedName;
|
||||||
|
TypeElement typeElement;
|
||||||
|
Type componentType;
|
||||||
|
|
||||||
DeclaredType declaredType = mirror.getKind() == TypeKind.DECLARED ? (DeclaredType) mirror : null;
|
|
||||||
|
|
||||||
if ( declaredType != null ) {
|
if ( mirror.getKind() == TypeKind.DECLARED ) {
|
||||||
|
DeclaredType declaredType = (DeclaredType) mirror;
|
||||||
|
|
||||||
isEnumType = declaredType.asElement().getKind() == ElementKind.ENUM;
|
isEnumType = declaredType.asElement().getKind() == ElementKind.ENUM;
|
||||||
isInterface = declaredType.asElement().getKind() == ElementKind.INTERFACE;
|
isInterface = declaredType.asElement().getKind() == ElementKind.INTERFACE;
|
||||||
name = declaredType.asElement().getSimpleName().toString();
|
name = declaredType.asElement().getSimpleName().toString();
|
||||||
@ -154,14 +157,40 @@ public class TypeFactory {
|
|||||||
packageName = null;
|
packageName = null;
|
||||||
qualifiedName = name;
|
qualifiedName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentType = null;
|
||||||
|
}
|
||||||
|
else if ( mirror.getKind() == TypeKind.ARRAY ) {
|
||||||
|
TypeMirror componentTypeMirror = getComponentType( mirror );
|
||||||
|
|
||||||
|
if ( componentTypeMirror.getKind() == TypeKind.DECLARED ) {
|
||||||
|
DeclaredType declaredType = (DeclaredType) componentTypeMirror;
|
||||||
|
TypeElement componentTypeElement =
|
||||||
|
declaredType.asElement().accept( new TypeElementRetrievalVisitor(), null );
|
||||||
|
|
||||||
|
name = componentTypeElement.getSimpleName().toString() + "[]";
|
||||||
|
packageName = elementUtils.getPackageOf( componentTypeElement ).getQualifiedName().toString();
|
||||||
|
qualifiedName = componentTypeElement.getQualifiedName().toString() + "[]";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = mirror.toString();
|
||||||
|
packageName = null;
|
||||||
|
qualifiedName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEnumType = false;
|
||||||
|
isInterface = false;
|
||||||
|
typeElement = null;
|
||||||
|
componentType = getType( componentTypeMirror );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
isEnumType = false;
|
isEnumType = false;
|
||||||
isInterface = false;
|
isInterface = false;
|
||||||
typeElement = null;
|
|
||||||
name = mirror.toString();
|
name = mirror.toString();
|
||||||
packageName = null;
|
packageName = null;
|
||||||
qualifiedName = name;
|
qualifiedName = name;
|
||||||
|
typeElement = null;
|
||||||
|
componentType = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Type(
|
return new Type(
|
||||||
@ -170,6 +199,7 @@ public class TypeFactory {
|
|||||||
typeElement,
|
typeElement,
|
||||||
getTypeParameters( mirror ),
|
getTypeParameters( mirror ),
|
||||||
implementationType,
|
implementationType,
|
||||||
|
componentType,
|
||||||
packageName,
|
packageName,
|
||||||
name,
|
name,
|
||||||
qualifiedName,
|
qualifiedName,
|
||||||
@ -354,6 +384,7 @@ public class TypeFactory {
|
|||||||
implementationType.getTypeElement(),
|
implementationType.getTypeElement(),
|
||||||
getTypeParameters( mirror ),
|
getTypeParameters( mirror ),
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
implementationType.getPackageName(),
|
implementationType.getPackageName(),
|
||||||
implementationType.getName(),
|
implementationType.getName(),
|
||||||
implementationType.getFullyQualifiedName(),
|
implementationType.getFullyQualifiedName(),
|
||||||
@ -369,6 +400,15 @@ public class TypeFactory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TypeMirror getComponentType(TypeMirror mirror) {
|
||||||
|
if ( mirror.getKind() != TypeKind.ARRAY ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayType arrayType = (ArrayType) mirror;
|
||||||
|
return arrayType.getComponentType();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isImported(String name, String qualifiedName) {
|
private boolean isImported(String name, String qualifiedName) {
|
||||||
String importedType = importedQualifiedTypesBySimpleName.get( name );
|
String importedType = importedQualifiedTypesBySimpleName.get( name );
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public class ForgedMethod implements Method {
|
|||||||
* @param positionHintElement element used to for reference to the position in the source file.
|
* @param positionHintElement element used to for reference to the position in the source file.
|
||||||
*/
|
*/
|
||||||
public ForgedMethod(Type sourceType, Type targetType, ExecutableElement positionHintElement) {
|
public ForgedMethod(Type sourceType, Type targetType, ExecutableElement positionHintElement) {
|
||||||
String sourceParamName = Strings.decapitalize( sourceType.getName() );
|
String sourceParamName = Strings.decapitalize( sourceType.getName().replace( "[]", "" ) );
|
||||||
String sourceParamSafeName = Strings.getSaveVariableName( sourceParamName );
|
String sourceParamSafeName = Strings.getSaveVariableName( sourceParamName );
|
||||||
this.parameters = Arrays.asList( new Parameter( sourceParamSafeName, sourceType ) );
|
this.parameters = Arrays.asList( new Parameter( sourceParamSafeName, sourceType ) );
|
||||||
this.returnType = targetType;
|
this.returnType = targetType;
|
||||||
@ -72,7 +72,7 @@ public class ForgedMethod implements Method {
|
|||||||
* @param positionHintElement element used to for reference to the position in the source file.
|
* @param positionHintElement element used to for reference to the position in the source file.
|
||||||
*/
|
*/
|
||||||
public ForgedMethod(String name, Type sourceType, Type targetType, ExecutableElement positionHintElement) {
|
public ForgedMethod(String name, Type sourceType, Type targetType, ExecutableElement positionHintElement) {
|
||||||
String sourceParamName = Strings.decapitalize( sourceType.getName() );
|
String sourceParamName = Strings.decapitalize( sourceType.getName().replace( "[]", "" ) );
|
||||||
String sourceParamSafeName = Strings.getSaveVariableName( sourceParamName );
|
String sourceParamSafeName = Strings.getSaveVariableName( sourceParamName );
|
||||||
this.parameters = Arrays.asList( new Parameter( sourceParamSafeName, sourceType ) );
|
this.parameters = Arrays.asList( new Parameter( sourceParamSafeName, sourceType ) );
|
||||||
this.returnType = targetType;
|
this.returnType = targetType;
|
||||||
@ -83,9 +83,10 @@ public class ForgedMethod implements Method {
|
|||||||
private String getName(Type type) {
|
private String getName(Type type) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for ( Type typeParam : type.getTypeParameters() ) {
|
for ( Type typeParam : type.getTypeParameters() ) {
|
||||||
builder.append( typeParam.getName() );
|
|
||||||
|
builder.append( typeParam.getName().replace( "[]", "Array" ) );
|
||||||
}
|
}
|
||||||
builder.append( type.getName() );
|
builder.append( type.getName().replace( "[]", "Array" ) );
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
package ${packageName};
|
package ${packageName};
|
||||||
|
|
||||||
<#list importTypes as importedType>
|
<#list importTypes as importedType>
|
||||||
import ${importedType.fullyQualifiedName};
|
import ${importedType.importName};
|
||||||
</#list>
|
</#list>
|
||||||
|
|
||||||
@Generated(
|
@Generated(
|
||||||
|
@ -22,29 +22,58 @@
|
|||||||
<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) <@throws/> {
|
<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, </#if></#list>) <@throws/> {
|
||||||
if ( ${sourceParameter.name} == null ) {
|
if ( ${sourceParameter.name} == null ) {
|
||||||
<#if !mapNullToDefault>
|
<#if !mapNullToDefault>
|
||||||
|
<#-- returned target type starts to miss-align here with target handed via param, TODO is this right? -->
|
||||||
return<#if returnType.name != "void"> null</#if>;
|
return<#if returnType.name != "void"> null</#if>;
|
||||||
|
<#else>
|
||||||
|
<#if resultType.arrayType>
|
||||||
|
<#if existingInstanceMapping>
|
||||||
|
<#-- we can't clear an existing array, so we've got to clear by setting values to default -->
|
||||||
|
for (int ${index2Name} = 0; ${index2Name} < ${resultName}.length; ${index2Name}++ ) {
|
||||||
|
${resultName}[${index2Name}] = ${defaultValue};
|
||||||
|
}
|
||||||
|
return<#if returnType.name != "void"> ${resultName}</#if>;
|
||||||
|
<#else>
|
||||||
|
return new <@includeModel object=resultElementType/>[];
|
||||||
|
</#if>
|
||||||
<#else>
|
<#else>
|
||||||
<#if existingInstanceMapping>
|
<#if existingInstanceMapping>
|
||||||
${resultName}.clear();
|
${resultName}.clear();
|
||||||
return<#if returnType.name != "void"> ${resultName} </#if>;
|
return<#if returnType.name != "void"> ${resultName}</#if>;
|
||||||
<#else>
|
<#else>
|
||||||
return <@returnObjectCreation/>;
|
return <@iterableCreation/>;
|
||||||
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<#if resultType.arrayType>
|
||||||
|
<#if !existingInstanceMapping>
|
||||||
|
<@includeModel object=resultElementType/>[] ${resultName} = new <@includeModel object=resultElementType/>[ <@iterableSize/> ];
|
||||||
|
</#if>
|
||||||
|
int ${index1Name} = 0;
|
||||||
|
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
|
||||||
|
<#if existingInstanceMapping>
|
||||||
|
if ( ( ${index1Name} >= ${resultName}.length ) || ( ${index1Name} >= <@iterableSize/> ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
</#if>
|
||||||
|
<@includeModel object=elementAssignment targetAccessorName=resultName+"[${index1Name}]" targetType=resultElementType isTargetDefined=true/>
|
||||||
|
${index1Name}++;
|
||||||
|
}
|
||||||
|
<#else>
|
||||||
<#if existingInstanceMapping>
|
<#if existingInstanceMapping>
|
||||||
${resultName}.clear();
|
${resultName}.clear();
|
||||||
<#else>
|
<#else>
|
||||||
<#-- Use the interface type on the left side, except it is java.lang.Iterable; use the implementation type - if present - on the right side -->
|
<#-- Use the interface type on the left side, except it is java.lang.Iterable; use the implementation type - if present - on the right side -->
|
||||||
<@localVarDefinition/> = <@returnObjectCreation/>;
|
<@iterableLocalVarDef/> ${resultName} = <@iterableCreation/>;
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
for ( <@includeModel object=sourceParameter.type.typeParameters[0]/> ${loopVariableName} : ${sourceParameter.name} ) {
|
for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) {
|
||||||
<@includeModel object=elementAssignment targetBeanName=resultName targetAccessorName="add" targetType=resultType.typeParameters[0]/>
|
<@includeModel object=elementAssignment targetBeanName=resultName targetAccessorName="add" targetType=resultElementType/>
|
||||||
}
|
}
|
||||||
<#if returnType.name != "void">
|
</#if>
|
||||||
|
|
||||||
|
<#if returnType.name != "void">
|
||||||
return ${resultName};
|
return ${resultName};
|
||||||
</#if>
|
</#if>
|
||||||
}
|
}
|
||||||
@ -57,16 +86,25 @@
|
|||||||
</#list>
|
</#list>
|
||||||
</@compress>
|
</@compress>
|
||||||
</#macro>
|
</#macro>
|
||||||
<#macro localVarDefinition>
|
<#macro iterableSize>
|
||||||
|
<@compress single_line=true>
|
||||||
|
<#if sourceParameter.type.arrayType>
|
||||||
|
${sourceParameter.name}.length
|
||||||
|
<#else>
|
||||||
|
${sourceParameter.name}.size()
|
||||||
|
</#if>
|
||||||
|
</@compress>
|
||||||
|
</#macro>
|
||||||
|
<#macro iterableLocalVarDef>
|
||||||
<@compress single_line=true>
|
<@compress single_line=true>
|
||||||
<#if resultType.fullyQualifiedName == "java.lang.Iterable">
|
<#if resultType.fullyQualifiedName == "java.lang.Iterable">
|
||||||
<@includeModel object=resultType.implementationType/>
|
<@includeModel object=resultType.implementationType/>
|
||||||
<#else>
|
<#else>
|
||||||
<@includeModel object=resultType/>
|
<@includeModel object=resultType/>
|
||||||
</#if> ${resultName}
|
</#if>
|
||||||
</@compress>
|
</@compress>
|
||||||
</#macro>
|
</#macro>
|
||||||
<#macro returnObjectCreation>
|
<#macro iterableCreation>
|
||||||
<@compress single_line=true>
|
<@compress single_line=true>
|
||||||
<#if factoryMethod??>
|
<#if factoryMethod??>
|
||||||
<@includeModel object=factoryMethod/>
|
<@includeModel object=factoryMethod/>
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
<#--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<#if (exceptionTypes?size == 0) >
|
||||||
|
<@includeModel object=ext.targetType/> ${localVarName} = <@_assignment/>;
|
||||||
|
${ext.targetBeanName}.${ext.targetAccessorName}( Arrays.copyOf( ${localVarName}, ${localVarName}.length ) );
|
||||||
|
<#else>
|
||||||
|
try {
|
||||||
|
<@includeModel object=ext.targetType/> ${localVarName} = <@_assignment/>;
|
||||||
|
${ext.targetBeanName}.${ext.targetAccessorName}( Arrays.copyOf( ${localVarName}, ${localVarName}.length ) );
|
||||||
|
}
|
||||||
|
<#list exceptionTypes as exceptionType>
|
||||||
|
catch ( <@includeModel object=exceptionType/> e ) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
<#macro _assignment>
|
||||||
|
<@includeModel object=assignment raw=ext.raw targetType=ext.targetType/>
|
||||||
|
</#macro>
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<#if (exceptionTypes?size == 0) >
|
<#if (exceptionTypes?size == 0) >
|
||||||
${ext.targetType.name} ${ext.targetAccessorName} = <@includeModel object=assignment targetType=ext.targetType raw=ext.raw/>;
|
<#if !ext.isTargetDefined?? >${ext.targetType.name}</#if> ${ext.targetAccessorName} = <@includeModel object=assignment targetType=ext.targetType raw=ext.raw/>;
|
||||||
<#else>
|
<#else>
|
||||||
${ext.targetType.name} ${ext.targetAccessorName};
|
<#if !ext.isTargetDefined?? >${ext.targetType.name} ${ext.targetAccessorName};</#if>
|
||||||
try {
|
try {
|
||||||
${ext.targetAccessorName} = <@includeModel object=assignment targetType=ext.targetType raw=ext.raw/>;
|
${ext.targetAccessorName} = <@includeModel object=assignment targetType=ext.targetType raw=ext.raw/>;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,223 @@
|
|||||||
|
/**
|
||||||
|
* 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.test.array;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mapstruct.ap.test.array.source.Scientist;
|
||||||
|
import org.mapstruct.ap.test.array.target.ScientistDto;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
|
|
||||||
|
@WithClasses( { Scientist.class, ScientistDto.class, ScienceMapper.class } )
|
||||||
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
@IssueKey("108")
|
||||||
|
public class ArrayMappingTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldCopyArraysInBean() {
|
||||||
|
|
||||||
|
Scientist source = new Scientist("Bob");
|
||||||
|
source.setPublications( new String[]{ "the Lancet", "Nature" } );
|
||||||
|
|
||||||
|
ScientistDto dto = ScienceMapper.INSTANCE.scientistToDto( source );
|
||||||
|
|
||||||
|
assertThat( dto ).isNotNull();
|
||||||
|
assertThat( dto ).isNotEqualTo( source );
|
||||||
|
assertThat( dto.getPublications() ).containsOnly( "the Lancet", "Nature");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldForgeMappingForIntToString() {
|
||||||
|
|
||||||
|
Scientist source = new Scientist("Bob");
|
||||||
|
source.setPublicationYears( new String[]{"1993", "1997"} );
|
||||||
|
|
||||||
|
ScientistDto dto = ScienceMapper.INSTANCE.scientistToDto( source );
|
||||||
|
|
||||||
|
assertThat( dto ).isNotNull();
|
||||||
|
assertThat( dto.getPublicationYears() ).containsOnly( 1993, 1997 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapArrayToArray() {
|
||||||
|
ScientistDto[] dtos = ScienceMapper.INSTANCE
|
||||||
|
.scientistsToDtos( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) } );
|
||||||
|
|
||||||
|
assertThat( dtos ).isNotNull();
|
||||||
|
assertThat( dtos ).onProperty( "name" ).containsOnly( "Bob", "Larry" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapListToArray() {
|
||||||
|
ScientistDto[] dtos = ScienceMapper.INSTANCE
|
||||||
|
.scientistsToDtos( Arrays.asList( new Scientist( "Bob" ), new Scientist( "Larry" ) ) );
|
||||||
|
|
||||||
|
assertThat( dtos ).isNotNull();
|
||||||
|
assertThat( dtos ).onProperty( "name" ).containsOnly( "Bob", "Larry" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapArrayToList() {
|
||||||
|
List<ScientistDto> dtos = ScienceMapper.INSTANCE
|
||||||
|
.scientistsToDtosAsList( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) } );
|
||||||
|
|
||||||
|
assertThat( dtos ).isNotNull();
|
||||||
|
assertThat( dtos ).onProperty( "name" ).containsOnly( "Bob", "Larry" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapArrayToArrayExistingSmallerSizedTarget() {
|
||||||
|
|
||||||
|
ScientistDto[] existingTarget = new ScientistDto[]{ new ScientistDto( "Jim" ) };
|
||||||
|
|
||||||
|
ScientistDto[] target = ScienceMapper.INSTANCE
|
||||||
|
.scientistsToDtos( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) }, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target ).isEqualTo( existingTarget );
|
||||||
|
assertThat( target ).onProperty( "name" ).containsOnly( "Bob" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapArrayToArrayExistingEqualSizedTarget() {
|
||||||
|
|
||||||
|
ScientistDto[] existingTarget = new ScientistDto[]{ new ScientistDto( "Jim" ), new ScientistDto( "Bart" ) };
|
||||||
|
|
||||||
|
ScientistDto[] target = ScienceMapper.INSTANCE
|
||||||
|
.scientistsToDtos( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) }, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target ).isEqualTo( existingTarget );
|
||||||
|
assertThat( target ).onProperty( "name" ).containsOnly( "Bob", "Larry" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapArrayToArrayExistingLargerSizedTarget() {
|
||||||
|
|
||||||
|
ScientistDto[] existingTarget =
|
||||||
|
new ScientistDto[]{ new ScientistDto( "Jim" ), new ScientistDto( "Bart" ), new ScientistDto( "John" ) };
|
||||||
|
|
||||||
|
ScientistDto[] target = ScienceMapper.INSTANCE
|
||||||
|
.scientistsToDtos( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) }, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target ).isEqualTo( existingTarget );
|
||||||
|
assertThat( target ).onProperty( "name" ).containsOnly( "Bob", "Larry", "John" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapTargetToNullWhenNullSource() {
|
||||||
|
// TODO: What about existing target?
|
||||||
|
|
||||||
|
ScientistDto[] existingTarget =
|
||||||
|
new ScientistDto[]{ new ScientistDto( "Jim" ) };
|
||||||
|
|
||||||
|
ScientistDto[] target = ScienceMapper.INSTANCE.scientistsToDtos( null, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).isNull();
|
||||||
|
assertThat( existingTarget ).onProperty( "name" ).containsOnly( "Jim" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapbooleanWhenReturnDefault() {
|
||||||
|
|
||||||
|
boolean[] existingTarget = new boolean[]{true};
|
||||||
|
boolean[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).containsOnly( false );
|
||||||
|
assertThat( existingTarget ).containsOnly( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapshortWhenReturnDefault() {
|
||||||
|
short[] existingTarget = new short[]{ 5 };
|
||||||
|
short[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).containsOnly( new short[] { 0 } );
|
||||||
|
assertThat( existingTarget ).containsOnly( new short[] { 0 } );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapcharWhenReturnDefault() {
|
||||||
|
char[] existingTarget = new char[]{ 'a' };
|
||||||
|
char[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).containsOnly( new char[] { 0 } );
|
||||||
|
assertThat( existingTarget ).containsOnly( new char[] { 0 } );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapintWhenReturnDefault() {
|
||||||
|
int[] existingTarget = new int[]{ 5 };
|
||||||
|
int[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).containsOnly( new int[] { 0 } );
|
||||||
|
assertThat( existingTarget ).containsOnly( new int[] { 0 } );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMaplongWhenReturnDefault() {
|
||||||
|
long[] existingTarget = new long[]{ 5L };
|
||||||
|
long[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).containsOnly( new long[] { 0L } );
|
||||||
|
assertThat( existingTarget ).containsOnly( new long[] { 0L } );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapfloatWhenReturnDefault() {
|
||||||
|
float[] existingTarget = new float[]{ 3.1f };
|
||||||
|
float[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).containsOnly( new float[] { 0.0f } );
|
||||||
|
assertThat( existingTarget ).containsOnly( new float[] { 0.0f } );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapdoubleWhenReturnDefault() {
|
||||||
|
double[] existingTarget = new double[]{ 5.0d };
|
||||||
|
double[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
|
||||||
|
|
||||||
|
assertThat( target ).containsOnly( new double[] { 0.0d } );
|
||||||
|
assertThat( existingTarget ).containsOnly( new double[] { 0.0d } );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldVoidMapintWhenReturnNull() {
|
||||||
|
long[] existingTarget = new long[]{ 5L };
|
||||||
|
ScienceMapper.INSTANCE.nvmMappingVoidReturnNull( null, existingTarget );
|
||||||
|
assertThat( existingTarget ).containsOnly( new long[] { 5L } );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldVoidMapintWhenReturnDefault() {
|
||||||
|
long[] existingTarget = new long[]{ 5L };
|
||||||
|
ScienceMapper.INSTANCE.nvmMappingVoidReturnDefault( null, existingTarget );
|
||||||
|
assertThat( existingTarget ).containsOnly( new long[] { 0L } );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* 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.test.array;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.NullValueMapping;
|
||||||
|
import org.mapstruct.NullValueMappingStrategy;
|
||||||
|
import org.mapstruct.ap.test.array.source.Scientist;
|
||||||
|
import org.mapstruct.ap.test.array.target.ScientistDto;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface ScienceMapper {
|
||||||
|
|
||||||
|
ScienceMapper INSTANCE = Mappers.getMapper( ScienceMapper.class );
|
||||||
|
|
||||||
|
ScientistDto scientistToDto(Scientist scientist);
|
||||||
|
|
||||||
|
ScientistDto[] scientistsToDtos(Scientist[] scientists);
|
||||||
|
|
||||||
|
ScientistDto[] scientistsToDtos(List<Scientist> scientists);
|
||||||
|
|
||||||
|
List<ScientistDto> scientistsToDtosAsList(Scientist[] scientists);
|
||||||
|
|
||||||
|
ScientistDto[] scientistsToDtos(Scientist[] scientists, @MappingTarget ScientistDto[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
boolean[] nvmMapping(boolean[] source, @MappingTarget boolean[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
short[] nvmMapping(int[] source, @MappingTarget short[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
char[] nvmMapping(String[] source, @MappingTarget char[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
int[] nvmMapping(int[] source, @MappingTarget int[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
long[] nvmMapping(int[] source, @MappingTarget long[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
float[] nvmMapping(int[] source, @MappingTarget float[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
double[] nvmMapping(int[] source, @MappingTarget double[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
String[] nvmMapping(int[] source, @MappingTarget String[] target);
|
||||||
|
|
||||||
|
void nvmMappingVoidReturnNull(int[] source, @MappingTarget long[] target);
|
||||||
|
|
||||||
|
@NullValueMapping( NullValueMappingStrategy.RETURN_DEFAULT )
|
||||||
|
void nvmMappingVoidReturnDefault(int[] source, @MappingTarget long[] target);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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.test.array.source;
|
||||||
|
|
||||||
|
public class Scientist {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String[] publications;
|
||||||
|
private String[] publicationYears;
|
||||||
|
|
||||||
|
|
||||||
|
public Scientist(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getPublications() {
|
||||||
|
return publications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublications(String[] publications) {
|
||||||
|
this.publications = publications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getPublicationYears() {
|
||||||
|
return publicationYears;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicationYears(String[] publicationYears) {
|
||||||
|
this.publicationYears = publicationYears;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package org.mapstruct.ap.test.array.target;
|
||||||
|
|
||||||
|
public class ScientistDto {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String[] publications;
|
||||||
|
private int[] publicationYears;
|
||||||
|
|
||||||
|
public ScientistDto() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScientistDto(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getPublications() {
|
||||||
|
return publications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublications(String[] publications) {
|
||||||
|
this.publications = publications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getPublicationYears() {
|
||||||
|
return publicationYears;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicationYears(int[] publicationYears) {
|
||||||
|
this.publicationYears = publicationYears;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -92,6 +92,20 @@ public class DateConversionTest {
|
|||||||
assertThat( stringDates ).containsExactly( "06.07.2013", "14.02.2013", "11.04.2013" );
|
assertThat( stringDates ).containsExactly( "06.07.2013", "14.02.2013", "11.04.2013" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldApplyStringConversionForArrayMethod() {
|
||||||
|
List<Date> dates = Arrays.asList(
|
||||||
|
new GregorianCalendar( 2013, 6, 6 ).getTime(),
|
||||||
|
new GregorianCalendar( 2013, 1, 14 ).getTime(),
|
||||||
|
new GregorianCalendar( 2013, 3, 11 ).getTime()
|
||||||
|
);
|
||||||
|
|
||||||
|
String[] stringDates = SourceTargetMapper.INSTANCE.stringListToDateArray( dates );
|
||||||
|
|
||||||
|
assertThat( stringDates ).isNotNull();
|
||||||
|
assertThat( stringDates ).isEqualTo( new String[]{ "06.07.2013", "14.02.2013", "11.04.2013" } );
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldApplyStringConversionForReverseIterableMethod() {
|
public void shouldApplyStringConversionForReverseIterableMethod() {
|
||||||
List<String> stringDates = Arrays.asList( "06.07.2013", "14.02.2013", "11.04.2013" );
|
List<String> stringDates = Arrays.asList( "06.07.2013", "14.02.2013", "11.04.2013" );
|
||||||
@ -105,4 +119,46 @@ public class DateConversionTest {
|
|||||||
new GregorianCalendar( 2013, 3, 11 ).getTime()
|
new GregorianCalendar( 2013, 3, 11 ).getTime()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldApplyStringConversionForReverseArrayMethod() {
|
||||||
|
String[] stringDates = new String[]{ "06.07.2013", "14.02.2013", "11.04.2013" };
|
||||||
|
|
||||||
|
List<Date> dates = SourceTargetMapper.INSTANCE.stringArrayToDateList( stringDates );
|
||||||
|
|
||||||
|
assertThat( dates ).isNotNull();
|
||||||
|
assertThat( dates ).containsExactly(
|
||||||
|
new GregorianCalendar( 2013, 6, 6 ).getTime(),
|
||||||
|
new GregorianCalendar( 2013, 1, 14 ).getTime(),
|
||||||
|
new GregorianCalendar( 2013, 3, 11 ).getTime()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldApplyStringConversionForReverseArrayArrayMethod() {
|
||||||
|
Date[] dates = new Date[]{
|
||||||
|
new GregorianCalendar( 2013, 6, 6 ).getTime(),
|
||||||
|
new GregorianCalendar( 2013, 1, 14 ).getTime(),
|
||||||
|
new GregorianCalendar( 2013, 3, 11 ).getTime()
|
||||||
|
};
|
||||||
|
String[] stringDates = SourceTargetMapper.INSTANCE.dateArrayToStringArray( dates );
|
||||||
|
|
||||||
|
assertThat( stringDates ).isNotNull();
|
||||||
|
assertThat( stringDates ).isEqualTo( new String[]{ "06.07.2013", "14.02.2013", "11.04.2013" } );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldApplyDateConversionForReverseArrayArrayMethod() {
|
||||||
|
|
||||||
|
String[] stringDates = new String[]{ "06.07.2013", "14.02.2013", "11.04.2013" };
|
||||||
|
Date[] dates = SourceTargetMapper.INSTANCE.stringArrayToDateArray( stringDates );
|
||||||
|
|
||||||
|
assertThat( dates ).isNotNull();
|
||||||
|
assertThat( dates ).isEqualTo( new Date[] {
|
||||||
|
new GregorianCalendar( 2013, 6, 6 ).getTime(),
|
||||||
|
new GregorianCalendar( 2013, 1, 14 ).getTime(),
|
||||||
|
new GregorianCalendar( 2013, 3, 11 ).getTime()
|
||||||
|
} );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,18 @@ public interface SourceTargetMapper {
|
|||||||
@IterableMapping(dateFormat = "dd.MM.yyyy")
|
@IterableMapping(dateFormat = "dd.MM.yyyy")
|
||||||
List<String> stringListToDateList(List<Date> dates);
|
List<String> stringListToDateList(List<Date> dates);
|
||||||
|
|
||||||
|
@IterableMapping(dateFormat = "dd.MM.yyyy")
|
||||||
|
String[] stringListToDateArray(List<Date> dates);
|
||||||
|
|
||||||
@InheritInverseConfiguration
|
@InheritInverseConfiguration
|
||||||
List<Date> dateListToStringList(List<String> strings);
|
List<Date> dateListToStringList(List<String> strings);
|
||||||
|
|
||||||
|
@InheritInverseConfiguration
|
||||||
|
List<Date> stringArrayToDateList(String[] dates);
|
||||||
|
|
||||||
|
@IterableMapping(dateFormat = "dd.MM.yyyy")
|
||||||
|
String[] dateArrayToStringArray(Date[] dates);
|
||||||
|
|
||||||
|
@InheritInverseConfiguration
|
||||||
|
Date[] stringArrayToDateArray(String[] dates);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user