mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-26 00:00:05 +08:00
#1126 Add new CollectionMappingStrategy TARGET_IMMUTABLE
This commit is contained in:
parent
cab7596a47
commit
e154452d53
@ -30,7 +30,8 @@ public enum CollectionMappingStrategy {
|
|||||||
* {@code orderDto.setOrderLines(order.getOrderLines)}.
|
* {@code orderDto.setOrderLines(order.getOrderLines)}.
|
||||||
* <p>
|
* <p>
|
||||||
* If no setter is available but a getter method, this will be used, under the assumption it has been initialized:
|
* If no setter is available but a getter method, this will be used, under the assumption it has been initialized:
|
||||||
* {@code orderDto.getOrderLines().addAll(order.getOrderLines)}.
|
* {@code orderDto.getOrderLines().addAll(order.getOrderLines)}. This will also be the case when using
|
||||||
|
* {@link MappingTarget} (updating existing instances).
|
||||||
*/
|
*/
|
||||||
ACCESSOR_ONLY,
|
ACCESSOR_ONLY,
|
||||||
|
|
||||||
@ -51,5 +52,13 @@ public enum CollectionMappingStrategy {
|
|||||||
* Identical to {@link #SETTER_PREFERRED}, only that adder methods will be preferred over setter methods, if both
|
* Identical to {@link #SETTER_PREFERRED}, only that adder methods will be preferred over setter methods, if both
|
||||||
* are present for a given collection-typed property.
|
* are present for a given collection-typed property.
|
||||||
*/
|
*/
|
||||||
ADDER_PREFERRED;
|
ADDER_PREFERRED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identical to {@link #SETTER_PREFERRED}, however the target collection will not be cleared and accessed via
|
||||||
|
* addAll in case of updating existing bean instances, see: {@link MappingTarget}.
|
||||||
|
*
|
||||||
|
* Instead the target accessor (e.g. set) will be used on the target bean to set the collection.
|
||||||
|
*/
|
||||||
|
TARGET_IMMUTABLE;
|
||||||
}
|
}
|
||||||
|
@ -1338,7 +1338,7 @@ public Map<Long, Date> stringStringMapToLongDateMap(Map<String, String> source)
|
|||||||
[[collection-mapping-strategies]]
|
[[collection-mapping-strategies]]
|
||||||
=== Collection mapping strategies
|
=== Collection mapping strategies
|
||||||
|
|
||||||
MapStruct has a `CollectionMappingStrategy`, with the possible values: `ACCESSOR_ONLY`, `SETTER_PREFERRED` and `ADDER_PREFERRED`.
|
MapStruct has a `CollectionMappingStrategy`, with the possible values: `ACCESSOR_ONLY`, `SETTER_PREFERRED`, `ADDER_PREFERRED` and `TARGET_IMMUTABLE`.
|
||||||
|
|
||||||
In the table below, the dash `-` indicates a property name. Next, the trailing `s` indicates the plural form. The table explains the options and how they are apply to the presence/absense of a `set-s`, `add-` and / or `get-s` method on the target object:
|
In the table below, the dash `-` indicates a property name. Next, the trailing `s` indicates the plural form. The table explains the options and how they are apply to the presence/absense of a `set-s`, `add-` and / or `get-s` method on the target object:
|
||||||
|
|
||||||
@ -1366,6 +1366,13 @@ In the table below, the dash `-` indicates a property name. Next, the trailing `
|
|||||||
|add-
|
|add-
|
||||||
|get-s
|
|get-s
|
||||||
|get-s
|
|get-s
|
||||||
|
|
||||||
|
|`TARGET_IMMUTABLE`
|
||||||
|
|set-s
|
||||||
|
|exception
|
||||||
|
|set-s
|
||||||
|
|exception
|
||||||
|
|set-s
|
||||||
|===
|
|===
|
||||||
|
|
||||||
Some background: An `adder` method is typically used in case of http://www.eclipse.org/webtools/dali/[generated (JPA) entities], to add a single element (entity) to an underlying collection. Invoking the adder establishes a parent-child relation between parent - the bean (entity) on which the adder is invoked - and its child(ren), the elements (entities) in the collection. To find the appropriate `adder`, MapStruct will try to make a match between the generic parameter type of the underlying collection and the single argument of a candidate `adder`. When there are more candidates, the plural `setter` / `getter` name is converted to singular and will be used in addition to make a match.
|
Some background: An `adder` method is typically used in case of http://www.eclipse.org/webtools/dali/[generated (JPA) entities], to add a single element (entity) to an underlying collection. Invoking the adder establishes a parent-child relation between parent - the bean (entity) on which the adder is invoked - and its child(ren), the elements (entities) in the collection. To find the appropriate `adder`, MapStruct will try to make a match between the generic parameter type of the underlying collection and the single argument of a candidate `adder`. When there are more candidates, the plural `setter` / `getter` name is converted to singular and will be used in addition to make a match.
|
||||||
|
@ -52,6 +52,7 @@ import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods;
|
|||||||
import org.mapstruct.ap.internal.model.source.PropertyEntry;
|
import org.mapstruct.ap.internal.model.source.PropertyEntry;
|
||||||
import org.mapstruct.ap.internal.model.source.SelectionParameters;
|
import org.mapstruct.ap.internal.model.source.SelectionParameters;
|
||||||
import org.mapstruct.ap.internal.model.source.SourceReference;
|
import org.mapstruct.ap.internal.model.source.SourceReference;
|
||||||
|
import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism;
|
||||||
import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism;
|
import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism;
|
||||||
import org.mapstruct.ap.internal.util.Executables;
|
import org.mapstruct.ap.internal.util.Executables;
|
||||||
import org.mapstruct.ap.internal.util.MapperConfiguration;
|
import org.mapstruct.ap.internal.util.MapperConfiguration;
|
||||||
@ -400,10 +401,15 @@ public class PropertyMapping extends ModelElement {
|
|||||||
|
|
||||||
Assignment result = rhs;
|
Assignment result = rhs;
|
||||||
|
|
||||||
if ( targetAccessorType == TargetWriteAccessorType.SETTER ||
|
CollectionMappingStrategyPrism cms = method.getMapperConfiguration().getCollectionMappingStrategy();
|
||||||
targetAccessorType == TargetWriteAccessorType.FIELD ) {
|
boolean targetImmutable = cms == CollectionMappingStrategyPrism.TARGET_IMMUTABLE;
|
||||||
|
|
||||||
|
if ( targetAccessorType == TargetWriteAccessorType.SETTER ||
|
||||||
|
targetAccessorType == TargetWriteAccessorType.FIELD ) {
|
||||||
|
|
||||||
|
|
||||||
|
if ( result.isCallingUpdateMethod() && !targetImmutable) {
|
||||||
|
|
||||||
if ( result.isCallingUpdateMethod() ) {
|
|
||||||
// call to an update method
|
// call to an update method
|
||||||
if ( targetReadAccessor == null ) {
|
if ( targetReadAccessor == null ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage(
|
||||||
@ -423,6 +429,7 @@ public class PropertyMapping extends ModelElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// target accessor is setter, so wrap the setter in setter map/ collection handling
|
// target accessor is setter, so wrap the setter in setter map/ collection handling
|
||||||
result = new SetterWrapperForCollectionsAndMaps(
|
result = new SetterWrapperForCollectionsAndMaps(
|
||||||
result,
|
result,
|
||||||
@ -430,11 +437,20 @@ public class PropertyMapping extends ModelElement {
|
|||||||
targetType,
|
targetType,
|
||||||
method.getMapperConfiguration().getNullValueCheckStrategy(),
|
method.getMapperConfiguration().getNullValueCheckStrategy(),
|
||||||
ctx.getTypeFactory(),
|
ctx.getTypeFactory(),
|
||||||
targetWriteAccessorType == TargetWriteAccessorType.FIELD
|
targetWriteAccessorType == TargetWriteAccessorType.FIELD,
|
||||||
|
targetImmutable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if ( targetImmutable ) {
|
||||||
|
ctx.getMessager().printMessage(
|
||||||
|
method.getExecutable(),
|
||||||
|
Message.PROPERTYMAPPING_NO_WRITE_ACCESSOR_FOR_TARGET_TYPE,
|
||||||
|
targetPropertyName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// target accessor is getter, so wrap the setter in getter map/ collection handling
|
// target accessor is getter, so wrap the setter in getter map/ collection handling
|
||||||
result = new GetterWrapperForCollectionsAndMaps( result,
|
result = new GetterWrapperForCollectionsAndMaps( result,
|
||||||
method.getThrownTypes(),
|
method.getThrownTypes(),
|
||||||
|
@ -47,13 +47,15 @@ public class SetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAnd
|
|||||||
private final boolean includeSourceNullCheck;
|
private final boolean includeSourceNullCheck;
|
||||||
private final Type targetType;
|
private final Type targetType;
|
||||||
private final TypeFactory typeFactory;
|
private final TypeFactory typeFactory;
|
||||||
|
private final boolean targetImmutable;
|
||||||
|
|
||||||
public SetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment,
|
public SetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment,
|
||||||
List<Type> thrownTypesToExclude,
|
List<Type> thrownTypesToExclude,
|
||||||
Type targetType,
|
Type targetType,
|
||||||
NullValueCheckStrategyPrism nvms,
|
NullValueCheckStrategyPrism nvms,
|
||||||
TypeFactory typeFactory,
|
TypeFactory typeFactory,
|
||||||
boolean fieldAssignment) {
|
boolean fieldAssignment,
|
||||||
|
boolean targetImmutable ) {
|
||||||
|
|
||||||
super(
|
super(
|
||||||
decoratedAssignment,
|
decoratedAssignment,
|
||||||
@ -64,6 +66,7 @@ public class SetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAnd
|
|||||||
this.includeSourceNullCheck = ALWAYS == nvms;
|
this.includeSourceNullCheck = ALWAYS == nvms;
|
||||||
this.targetType = targetType;
|
this.targetType = targetType;
|
||||||
this.typeFactory = typeFactory;
|
this.typeFactory = typeFactory;
|
||||||
|
this.targetImmutable = targetImmutable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -96,4 +99,8 @@ public class SetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAnd
|
|||||||
return "java.util.EnumSet".equals( targetType.getFullyQualifiedName() );
|
return "java.util.EnumSet".equals( targetType.getFullyQualifiedName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTargetImmutable() {
|
||||||
|
return targetImmutable;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -469,7 +469,8 @@ public class Type extends ModelElement implements Comparable<Type> {
|
|||||||
// the current target accessor can also be a getter method.
|
// the current target accessor can also be a getter method.
|
||||||
// The following if block, checks if the target accessor should be overruled by an add method.
|
// The following if block, checks if the target accessor should be overruled by an add method.
|
||||||
if ( cmStrategy == CollectionMappingStrategyPrism.SETTER_PREFERRED
|
if ( cmStrategy == CollectionMappingStrategyPrism.SETTER_PREFERRED
|
||||||
|| cmStrategy == CollectionMappingStrategyPrism.ADDER_PREFERRED ) {
|
|| cmStrategy == CollectionMappingStrategyPrism.ADDER_PREFERRED
|
||||||
|
|| cmStrategy == CollectionMappingStrategyPrism.TARGET_IMMUTABLE ) {
|
||||||
|
|
||||||
// first check if there's a setter method.
|
// first check if there's a setter method.
|
||||||
Accessor adderMethod = null;
|
Accessor adderMethod = null;
|
||||||
|
@ -27,5 +27,6 @@ public enum CollectionMappingStrategyPrism {
|
|||||||
|
|
||||||
ACCESSOR_ONLY,
|
ACCESSOR_ONLY,
|
||||||
SETTER_PREFERRED,
|
SETTER_PREFERRED,
|
||||||
ADDER_PREFERRED;
|
ADDER_PREFERRED,
|
||||||
|
TARGET_IMMUTABLE;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ public enum Message {
|
|||||||
PROPERTYMAPPING_INVALID_PROPERTY_NAME( "No property named \"%s\" exists in source parameter(s)." ),
|
PROPERTYMAPPING_INVALID_PROPERTY_NAME( "No property named \"%s\" exists in source parameter(s)." ),
|
||||||
PROPERTYMAPPING_NO_PRESENCE_CHECKER_FOR_SOURCE_TYPE( "Using custom source value presence checking strategy, but no presence checker found for %s in source type." ),
|
PROPERTYMAPPING_NO_PRESENCE_CHECKER_FOR_SOURCE_TYPE( "Using custom source value presence checking strategy, but no presence checker found for %s in source type." ),
|
||||||
PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ),
|
PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ),
|
||||||
|
PROPERTYMAPPING_NO_WRITE_ACCESSOR_FOR_TARGET_TYPE( "No write accessor found for property \"%s\" in target type." ),
|
||||||
|
|
||||||
CONSTANTMAPPING_MAPPING_NOT_FOUND( "Can't map \"%s %s\" to \"%s %s\"." ),
|
CONSTANTMAPPING_MAPPING_NOT_FOUND( "Can't map \"%s %s\" to \"%s %s\"." ),
|
||||||
CONSTANTMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ),
|
CONSTANTMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ),
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<#import "../macro/CommonMacros.ftl" as lib>
|
<#import "../macro/CommonMacros.ftl" as lib>
|
||||||
<@lib.sourceLocalVarAssignment/>
|
<@lib.sourceLocalVarAssignment/>
|
||||||
<@lib.handleExceptions>
|
<@lib.handleExceptions>
|
||||||
<#if ext.existingInstanceMapping>
|
<#if ext.existingInstanceMapping && !targetImmutable>
|
||||||
if ( ${ext.targetBeanName}.${ext.targetReadAccessorName} != null ) {
|
if ( ${ext.targetBeanName}.${ext.targetReadAccessorName} != null ) {
|
||||||
<@lib.handleLocalVarNullCheck>
|
<@lib.handleLocalVarNullCheck>
|
||||||
${ext.targetBeanName}.${ext.targetReadAccessorName}.clear();
|
${ext.targetBeanName}.${ext.targetReadAccessorName}.clear();
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.collection.immutabletarget;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class CupboardDto {
|
||||||
|
|
||||||
|
private List<String> content;
|
||||||
|
|
||||||
|
public List<String> getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(List<String> content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.collection.immutabletarget;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class CupboardEntity {
|
||||||
|
|
||||||
|
private List<String> content;
|
||||||
|
|
||||||
|
public List<String> getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(List<String> content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.collection.immutabletarget;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class CupboardEntityOnlyGetter {
|
||||||
|
|
||||||
|
private List<String> content;
|
||||||
|
|
||||||
|
public List<String> getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.collection.immutabletarget;
|
||||||
|
|
||||||
|
import org.mapstruct.CollectionMappingStrategy;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
@Mapper( collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE )
|
||||||
|
public interface CupboardMapper {
|
||||||
|
|
||||||
|
CupboardMapper INSTANCE = Mappers.getMapper( CupboardMapper.class );
|
||||||
|
|
||||||
|
void map( CupboardDto in, @MappingTarget CupboardEntity out );
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.collection.immutabletarget;
|
||||||
|
|
||||||
|
import org.mapstruct.CollectionMappingStrategy;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
@Mapper( collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE )
|
||||||
|
public interface ErroneousCupboardMapper {
|
||||||
|
|
||||||
|
ErroneousCupboardMapper INSTANCE = Mappers.getMapper( ErroneousCupboardMapper.class );
|
||||||
|
|
||||||
|
void map( CupboardDto in, @MappingTarget CupboardEntityOnlyGetter out );
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.collection.immutabletarget;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
|
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
|
||||||
|
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
|
||||||
|
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
|
||||||
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
@WithClasses({CupboardDto.class, CupboardEntity.class, CupboardMapper.class})
|
||||||
|
@IssueKey( "1126" )
|
||||||
|
public class ImmutableTargetTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldHandleImmutableTarget() {
|
||||||
|
|
||||||
|
CupboardDto in = new CupboardDto();
|
||||||
|
in.setContent( Arrays.asList( "cups", "soucers" ) );
|
||||||
|
CupboardEntity out = new CupboardEntity();
|
||||||
|
out.setContent( Collections.<String>emptyList() );
|
||||||
|
|
||||||
|
CupboardMapper.INSTANCE.map( in, out );
|
||||||
|
|
||||||
|
assertThat( out.getContent() ).isNotNull();
|
||||||
|
assertThat( out.getContent() ).containsExactly( "cups", "soucers" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithClasses({
|
||||||
|
ErroneousCupboardMapper.class,
|
||||||
|
CupboardEntityOnlyGetter.class
|
||||||
|
})
|
||||||
|
@ExpectedCompilationOutcome(
|
||||||
|
value = CompilationResult.FAILED,
|
||||||
|
diagnostics = {
|
||||||
|
@Diagnostic(type = ErroneousCupboardMapper.class,
|
||||||
|
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||||
|
line = 35,
|
||||||
|
messageRegExp = "No write accessor found for property \"content\" in target type.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public void testShouldFailOnPropertyMappingNoPropertySetterOnlyGetter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user