mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#487 iterable and map update method selection
This commit is contained in:
parent
c8e9f91037
commit
174c53cb48
@ -170,8 +170,7 @@ public class PropertyMapping extends ModelElement {
|
|||||||
|
|
||||||
// all the tricky cases will be excluded for the time being.
|
// all the tricky cases will be excluded for the time being.
|
||||||
boolean preferUpdateMethods;
|
boolean preferUpdateMethods;
|
||||||
if ( targetType.isCollectionOrMapType() || targetType.isArrayType() ||
|
if ( targetAccessorType == TargetWriteAccessorType.ADDER ) {
|
||||||
targetAccessorType == TargetWriteAccessorType.ADDER ) {
|
|
||||||
preferUpdateMethods = false;
|
preferUpdateMethods = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -253,7 +252,8 @@ public class PropertyMapping extends ModelElement {
|
|||||||
}
|
}
|
||||||
Assignment factoryMethod =
|
Assignment factoryMethod =
|
||||||
ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null );
|
ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null );
|
||||||
result = new UpdateWrapper( result, method.getThrownTypes(), factoryMethod );
|
result = new UpdateWrapper( result, method.getThrownTypes(), factoryMethod,
|
||||||
|
targetType.getImplementationType() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = new SetterWrapper( result, method.getThrownTypes() );
|
result = new SetterWrapper( result, method.getThrownTypes() );
|
||||||
@ -312,16 +312,29 @@ public class PropertyMapping extends ModelElement {
|
|||||||
newCollectionOrMap = new NewCollectionOrMapWrapper( result, implementationTypes );
|
newCollectionOrMap = new NewCollectionOrMapWrapper( result, implementationTypes );
|
||||||
newCollectionOrMap = new SetterWrapper( newCollectionOrMap, method.getThrownTypes() );
|
newCollectionOrMap = new SetterWrapper( newCollectionOrMap, method.getThrownTypes() );
|
||||||
}
|
}
|
||||||
|
if ( result.isUpdateMethod() ) {
|
||||||
|
if ( targetReadAccessor == null ) {
|
||||||
|
ctx.getMessager().printMessage( method.getExecutable(),
|
||||||
|
Message.PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE,
|
||||||
|
targetPropertyName );
|
||||||
|
}
|
||||||
|
Assignment factoryMethod
|
||||||
|
= ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null );
|
||||||
|
result = new UpdateWrapper( result, method.getThrownTypes(), factoryMethod,
|
||||||
|
targetType.getImplementationType() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// wrap the assignment in the setter method
|
||||||
|
result = new SetterWrapper( result, method.getThrownTypes() );
|
||||||
|
|
||||||
// wrap the assignment in the setter method
|
// target accessor is setter, so wrap the setter in setter map/ collection handling
|
||||||
result = new SetterWrapper( result, method.getThrownTypes() );
|
result = new SetterWrapperForCollectionsAndMaps(
|
||||||
|
result,
|
||||||
|
targetWriteAccessor,
|
||||||
|
newCollectionOrMap
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// target accessor is setter, so wrap the setter in setter map/ collection handling
|
|
||||||
result = new SetterWrapperForCollectionsAndMaps(
|
|
||||||
result,
|
|
||||||
targetWriteAccessor,
|
|
||||||
newCollectionOrMap
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 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
|
||||||
@ -589,7 +602,8 @@ public class PropertyMapping extends ModelElement {
|
|||||||
}
|
}
|
||||||
Assignment factoryMethod =
|
Assignment factoryMethod =
|
||||||
ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null );
|
ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null );
|
||||||
assignment = new UpdateWrapper( assignment, method.getThrownTypes(), factoryMethod );
|
assignment = new UpdateWrapper( assignment, method.getThrownTypes(), factoryMethod,
|
||||||
|
targetType.getImplementationType() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
|
assignment = new SetterWrapper( assignment, method.getThrownTypes() );
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
package org.mapstruct.ap.internal.model.assignment;
|
package org.mapstruct.ap.internal.model.assignment;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.mapstruct.ap.internal.model.common.Type;
|
import org.mapstruct.ap.internal.model.common.Type;
|
||||||
|
|
||||||
@ -32,11 +34,14 @@ public class UpdateWrapper extends AssignmentWrapper {
|
|||||||
|
|
||||||
private final List<Type> thrownTypesToExclude;
|
private final List<Type> thrownTypesToExclude;
|
||||||
private final Assignment factoryMethod;
|
private final Assignment factoryMethod;
|
||||||
|
private final Type targetImplementationType;
|
||||||
|
|
||||||
public UpdateWrapper(Assignment decoratedAssignment, List<Type> thrownTypesToExclude, Assignment factoryMethod ) {
|
public UpdateWrapper(Assignment decoratedAssignment, List<Type> thrownTypesToExclude, Assignment factoryMethod,
|
||||||
|
Type targetImplementationType ) {
|
||||||
super( decoratedAssignment );
|
super( decoratedAssignment );
|
||||||
this.thrownTypesToExclude = thrownTypesToExclude;
|
this.thrownTypesToExclude = thrownTypesToExclude;
|
||||||
this.factoryMethod = factoryMethod;
|
this.factoryMethod = factoryMethod;
|
||||||
|
this.targetImplementationType = targetImplementationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -53,6 +58,16 @@ public class UpdateWrapper extends AssignmentWrapper {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Type> getImportTypes() {
|
||||||
|
Set<Type> imported = new HashSet<Type>();
|
||||||
|
imported.addAll( super.getImportTypes() );
|
||||||
|
if ( targetImplementationType != null ) {
|
||||||
|
imported.add( targetImplementationType );
|
||||||
|
}
|
||||||
|
return imported;
|
||||||
|
}
|
||||||
|
|
||||||
public Assignment getFactoryMethod() {
|
public Assignment getFactoryMethod() {
|
||||||
return factoryMethod;
|
return factoryMethod;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
</#if>
|
</#if>
|
||||||
<#macro _assignment>
|
<#macro _assignment>
|
||||||
if ( ${ext.targetBeanName}.${ext.targetReadAccessorName}() == null ) {
|
if ( ${ext.targetBeanName}.${ext.targetReadAccessorName}() == null ) {
|
||||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <#if factoryMethod??><@includeModel object=factoryMethod targetType=ext.targetType/><#else>new <@includeModel object=ext.targetType/>()</#if> );
|
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <#if factoryMethod??><@includeModel object=factoryMethod targetType=ext.targetType/><#else><@_newObject/></#if> );
|
||||||
}
|
}
|
||||||
<@includeModel object=assignment
|
<@includeModel object=assignment
|
||||||
targetBeanName=ext.targetBeanName
|
targetBeanName=ext.targetBeanName
|
||||||
@ -40,4 +40,6 @@
|
|||||||
targetReadAccessorName=ext.targetReadAccessorName
|
targetReadAccessorName=ext.targetReadAccessorName
|
||||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||||
targetType=ext.targetType/>
|
targetType=ext.targetType/>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
<#macro _newObject>new <#if ext.targetType.implementationType??><@includeModel object=ext.targetType.implementationType/><#else><@includeModel object=ext.targetType/></#if>()</#macro>
|
||||||
|
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
package org.mapstruct.ap.test.updatemethods;
|
package org.mapstruct.ap.test.updatemethods;
|
||||||
|
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.MappingTarget;
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,6 +37,10 @@ public interface CompanyMapper {
|
|||||||
|
|
||||||
DepartmentInBetween toInBetween(DepartmentDto dto);
|
DepartmentInBetween toInBetween(DepartmentDto dto);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping( target = "employees", ignore = true ),
|
||||||
|
@Mapping( target = "secretaryToEmployee", ignore = true )
|
||||||
|
})
|
||||||
void toDepartmentEntity(DepartmentInBetween dto, @MappingTarget DepartmentEntity entity);
|
void toDepartmentEntity(DepartmentInBetween dto, @MappingTarget DepartmentEntity entity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.test.updatemethods;
|
package org.mapstruct.ap.test.updatemethods;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
@ -25,6 +28,8 @@ package org.mapstruct.ap.test.updatemethods;
|
|||||||
public class DepartmentDto {
|
public class DepartmentDto {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
private List<EmployeeDto> employees;
|
||||||
|
private Map<SecretaryDto, EmployeeDto> secretaryToEmployee;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
@ -34,4 +39,20 @@ public class DepartmentDto {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<EmployeeDto> getEmployees() {
|
||||||
|
return employees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmployees(List<EmployeeDto> employees) {
|
||||||
|
this.employees = employees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<SecretaryDto, EmployeeDto> getSecretaryToEmployee() {
|
||||||
|
return secretaryToEmployee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecretaryToEmployee(Map<SecretaryDto, EmployeeDto> secretaryToEmployee) {
|
||||||
|
this.secretaryToEmployee = secretaryToEmployee;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.test.updatemethods;
|
package org.mapstruct.ap.test.updatemethods;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
@ -25,6 +28,8 @@ package org.mapstruct.ap.test.updatemethods;
|
|||||||
public class DepartmentEntity {
|
public class DepartmentEntity {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
private List<EmployeeEntity> employees;
|
||||||
|
private Map<SecretaryEntity, EmployeeEntity> secretaryToEmployee;
|
||||||
|
|
||||||
public DepartmentEntity(Integer justAnArgToAvoidConstruction) {
|
public DepartmentEntity(Integer justAnArgToAvoidConstruction) {
|
||||||
}
|
}
|
||||||
@ -37,4 +42,20 @@ public class DepartmentEntity {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<EmployeeEntity> getEmployees() {
|
||||||
|
return employees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmployees(List<EmployeeEntity> employees) {
|
||||||
|
this.employees = employees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<SecretaryEntity, EmployeeEntity> getSecretaryToEmployee() {
|
||||||
|
return secretaryToEmployee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecretaryToEmployee(Map<SecretaryEntity, EmployeeEntity> secretaryToEmployee) {
|
||||||
|
this.secretaryToEmployee = secretaryToEmployee;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 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.updatemethods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class EmployeeDto {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 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.updatemethods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class EmployeeEntity {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,7 +19,9 @@
|
|||||||
package org.mapstruct.ap.test.updatemethods;
|
package org.mapstruct.ap.test.updatemethods;
|
||||||
|
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.MappingTarget;
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,5 +37,9 @@ public interface ErroneousCompanyMapper1 {
|
|||||||
|
|
||||||
void toInBetween(DepartmentDto dto, @MappingTarget DepartmentInBetween entity);
|
void toInBetween(DepartmentDto dto, @MappingTarget DepartmentInBetween entity);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping( target = "employees", ignore = true ),
|
||||||
|
@Mapping( target = "secretaryToEmployee", ignore = true )
|
||||||
|
})
|
||||||
void toDepartmentEntity(DepartmentInBetween dto, @MappingTarget DepartmentEntity entity);
|
void toDepartmentEntity(DepartmentInBetween dto, @MappingTarget DepartmentEntity entity);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ package org.mapstruct.ap.test.updatemethods;
|
|||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.MappingTarget;
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,6 +41,10 @@ public interface ErroneousOrganizationMapper1 {
|
|||||||
@Mapping(source = "type", target = "type")
|
@Mapping(source = "type", target = "type")
|
||||||
void toName(String type, @MappingTarget OrganizationTypeEntity entity);
|
void toName(String type, @MappingTarget OrganizationTypeEntity entity);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping( target = "employees", ignore = true ),
|
||||||
|
@Mapping( target = "secretaryToEmployee", ignore = true )
|
||||||
|
})
|
||||||
DepartmentEntity toDepartmentEntity(DepartmentDto dto);
|
DepartmentEntity toDepartmentEntity(DepartmentDto dto);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ package org.mapstruct.ap.test.updatemethods;
|
|||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.MappingTarget;
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,6 +41,10 @@ public interface ErroneousOrganizationMapper2 {
|
|||||||
@Mapping(source = "type", target = "type")
|
@Mapping(source = "type", target = "type")
|
||||||
void toName(String type, @MappingTarget OrganizationTypeEntity entity);
|
void toName(String type, @MappingTarget OrganizationTypeEntity entity);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping( target = "employees", ignore = true ),
|
||||||
|
@Mapping( target = "secretaryToEmployee", ignore = true )
|
||||||
|
})
|
||||||
DepartmentEntity toDepartmentEntity(DepartmentDto dto);
|
DepartmentEntity toDepartmentEntity(DepartmentDto dto);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,10 @@ public interface OrganizationMapper {
|
|||||||
|
|
||||||
void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity);
|
void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping( target = "employees", ignore = true ),
|
||||||
|
@Mapping( target = "secretaryToEmployee", ignore = true )
|
||||||
|
})
|
||||||
DepartmentEntity toDepartmentEntity(DepartmentDto dto);
|
DepartmentEntity toDepartmentEntity(DepartmentDto dto);
|
||||||
|
|
||||||
@Mapping(source = "type", target = "type")
|
@Mapping(source = "type", target = "type")
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 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.updatemethods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class SecretaryDto {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 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.updatemethods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public class SecretaryEntity {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -36,20 +36,26 @@ import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
|||||||
*/
|
*/
|
||||||
@IssueKey("160")
|
@IssueKey("160")
|
||||||
@RunWith(AnnotationProcessorTestRunner.class)
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
@WithClasses({
|
||||||
|
OrganizationDto.class,
|
||||||
|
OrganizationEntity.class,
|
||||||
|
CompanyDto.class,
|
||||||
|
CompanyEntity.class,
|
||||||
|
DepartmentDto.class,
|
||||||
|
DepartmentEntity.class,
|
||||||
|
DepartmentEntityFactory.class,
|
||||||
|
OrganizationTypeEntity.class,
|
||||||
|
OrganizationTypeNrEntity.class,
|
||||||
|
EmployeeDto.class,
|
||||||
|
EmployeeEntity.class,
|
||||||
|
SecretaryDto.class,
|
||||||
|
SecretaryEntity.class
|
||||||
|
})
|
||||||
public class UpdateMethodsTest {
|
public class UpdateMethodsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithClasses( {
|
@WithClasses( {
|
||||||
OrganizationMapper.class,
|
OrganizationMapper.class
|
||||||
OrganizationDto.class,
|
|
||||||
OrganizationEntity.class,
|
|
||||||
CompanyDto.class,
|
|
||||||
CompanyEntity.class,
|
|
||||||
DepartmentDto.class,
|
|
||||||
DepartmentEntity.class,
|
|
||||||
DepartmentEntityFactory.class,
|
|
||||||
OrganizationTypeEntity.class,
|
|
||||||
OrganizationTypeNrEntity.class
|
|
||||||
} )
|
} )
|
||||||
public void testPreferUpdateMethod() {
|
public void testPreferUpdateMethod() {
|
||||||
|
|
||||||
@ -77,16 +83,7 @@ public class UpdateMethodsTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithClasses( {
|
@WithClasses( {
|
||||||
OrganizationMapper.class,
|
OrganizationMapper.class
|
||||||
OrganizationDto.class,
|
|
||||||
OrganizationEntity.class,
|
|
||||||
CompanyDto.class,
|
|
||||||
CompanyEntity.class,
|
|
||||||
DepartmentDto.class,
|
|
||||||
DepartmentEntity.class,
|
|
||||||
DepartmentEntityFactory.class,
|
|
||||||
OrganizationTypeEntity.class,
|
|
||||||
OrganizationTypeNrEntity.class
|
|
||||||
} )
|
} )
|
||||||
public void testPreferUpdateMethodSourceObjectNotDefined() {
|
public void testPreferUpdateMethodSourceObjectNotDefined() {
|
||||||
|
|
||||||
@ -111,14 +108,7 @@ public class UpdateMethodsTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithClasses( {
|
@WithClasses( {
|
||||||
CompanyMapper.class,
|
CompanyMapper.class,
|
||||||
CompanyDto.class,
|
DepartmentInBetween.class
|
||||||
CompanyEntity.class,
|
|
||||||
DepartmentDto.class,
|
|
||||||
DepartmentInBetween.class,
|
|
||||||
DepartmentEntity.class,
|
|
||||||
DepartmentEntityFactory.class,
|
|
||||||
OrganizationTypeEntity.class,
|
|
||||||
OrganizationTypeNrEntity.class
|
|
||||||
} )
|
} )
|
||||||
public void testPreferUpdateMethodEncapsulatingCreateMethod() {
|
public void testPreferUpdateMethodEncapsulatingCreateMethod() {
|
||||||
|
|
||||||
@ -138,21 +128,14 @@ public class UpdateMethodsTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithClasses( {
|
@WithClasses( {
|
||||||
ErroneousOrganizationMapper1.class,
|
ErroneousOrganizationMapper1.class,
|
||||||
OrganizationDto.class,
|
OrganizationWithoutCompanyGetterEntity.class
|
||||||
OrganizationWithoutCompanyGetterEntity.class,
|
|
||||||
CompanyDto.class,
|
|
||||||
CompanyEntity.class,
|
|
||||||
DepartmentDto.class,
|
|
||||||
DepartmentEntity.class,
|
|
||||||
DepartmentEntityFactory.class,
|
|
||||||
OrganizationTypeEntity.class
|
|
||||||
} )
|
} )
|
||||||
@ExpectedCompilationOutcome(
|
@ExpectedCompilationOutcome(
|
||||||
value = CompilationResult.FAILED,
|
value = CompilationResult.FAILED,
|
||||||
diagnostics = {
|
diagnostics = {
|
||||||
@Diagnostic(type = ErroneousOrganizationMapper1.class,
|
@Diagnostic(type = ErroneousOrganizationMapper1.class,
|
||||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||||
line = 36,
|
line = 37,
|
||||||
messageRegExp = "No read accessor found for property \"company\" in target type.")
|
messageRegExp = "No read accessor found for property \"company\" in target type.")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -161,45 +144,30 @@ public class UpdateMethodsTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithClasses( {
|
@WithClasses( {
|
||||||
ErroneousOrganizationMapper2.class,
|
ErroneousOrganizationMapper2.class,
|
||||||
OrganizationDto.class,
|
OrganizationWithoutTypeGetterEntity.class
|
||||||
OrganizationWithoutTypeGetterEntity.class,
|
|
||||||
CompanyDto.class,
|
|
||||||
CompanyEntity.class,
|
|
||||||
DepartmentDto.class,
|
|
||||||
DepartmentEntity.class,
|
|
||||||
DepartmentEntityFactory.class,
|
|
||||||
OrganizationTypeEntity.class
|
|
||||||
} )
|
} )
|
||||||
@ExpectedCompilationOutcome(
|
@ExpectedCompilationOutcome(
|
||||||
value = CompilationResult.FAILED,
|
value = CompilationResult.FAILED,
|
||||||
diagnostics = {
|
diagnostics = {
|
||||||
@Diagnostic(type = ErroneousOrganizationMapper2.class,
|
@Diagnostic(type = ErroneousOrganizationMapper2.class,
|
||||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||||
line = 36,
|
line = 37,
|
||||||
messageRegExp = "No read accessor found for property \"type\" in target type.")
|
messageRegExp = "No read accessor found for property \"type\" in target type.")
|
||||||
}
|
} )
|
||||||
)
|
|
||||||
public void testShouldFailOnConstantMappingNoPropertyGetter() { }
|
public void testShouldFailOnConstantMappingNoPropertyGetter() { }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithClasses( {
|
@WithClasses( {
|
||||||
ErroneousCompanyMapper1.class,
|
ErroneousCompanyMapper1.class,
|
||||||
OrganizationDto.class,
|
DepartmentInBetween.class
|
||||||
OrganizationWithoutTypeGetterEntity.class,
|
|
||||||
CompanyDto.class,
|
|
||||||
CompanyEntity.class,
|
|
||||||
DepartmentDto.class,
|
|
||||||
DepartmentInBetween.class,
|
|
||||||
DepartmentEntity.class,
|
|
||||||
DepartmentEntityFactory.class,
|
|
||||||
OrganizationTypeEntity.class
|
|
||||||
} )
|
} )
|
||||||
@ExpectedCompilationOutcome(
|
@ExpectedCompilationOutcome(
|
||||||
value = CompilationResult.FAILED,
|
value = CompilationResult.FAILED,
|
||||||
diagnostics = {
|
diagnostics = {
|
||||||
@Diagnostic(type = ErroneousCompanyMapper1.class,
|
@Diagnostic(type = ErroneousCompanyMapper1.class,
|
||||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||||
line = 34,
|
line = 36,
|
||||||
messageRegExp = "Can't map property \".*DepartmentDto department\" to \".*DepartmentEntity department.")
|
messageRegExp = "Can't map property \".*DepartmentDto department\" to \".*DepartmentEntity department.")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 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.updatemethods.selection;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.DepartmentDto;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.DepartmentEntity;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.EmployeeDto;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.EmployeeEntity;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.SecretaryDto;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.SecretaryEntity;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
@Mapper( uses = ExternalHandWrittenMapper.class )
|
||||||
|
public interface DepartmentMapper {
|
||||||
|
|
||||||
|
DepartmentMapper INSTANCE = Mappers.getMapper( DepartmentMapper.class );
|
||||||
|
|
||||||
|
void toDepartmentEntity(DepartmentDto dto, @MappingTarget DepartmentEntity entity);
|
||||||
|
|
||||||
|
EmployeeEntity toEmployeeEntity(EmployeeDto dto);
|
||||||
|
|
||||||
|
SecretaryEntity toSecretaryEntity(SecretaryDto dto);
|
||||||
|
|
||||||
|
}
|
@ -18,9 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.test.updatemethods.selection;
|
package org.mapstruct.ap.test.updatemethods.selection;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import org.mapstruct.MappingTarget;
|
import org.mapstruct.MappingTarget;
|
||||||
import org.mapstruct.ap.test.updatemethods.DepartmentDto;
|
import org.mapstruct.ap.test.updatemethods.DepartmentDto;
|
||||||
import org.mapstruct.ap.test.updatemethods.DepartmentEntity;
|
import org.mapstruct.ap.test.updatemethods.DepartmentEntity;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.EmployeeDto;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.EmployeeEntity;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.SecretaryDto;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.SecretaryEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -35,4 +41,24 @@ public class ExternalHandWrittenMapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void toEmployeeEntityList(List<EmployeeDto> dtos, @MappingTarget List<EmployeeEntity> entities) {
|
||||||
|
|
||||||
|
if ( entities != null && dtos != null ) {
|
||||||
|
for ( EmployeeDto dto : dtos) {
|
||||||
|
entities.add( DepartmentMapper.INSTANCE.toEmployeeEntity( dto ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toSecretaryEmployeeEntityMap(Map<SecretaryDto, EmployeeDto> dtoMap,
|
||||||
|
@MappingTarget Map<SecretaryEntity, EmployeeEntity> entityMap) {
|
||||||
|
|
||||||
|
if ( entityMap != null && dtoMap != null ) {
|
||||||
|
for ( Map.Entry<SecretaryDto, EmployeeDto> dtoEntry : dtoMap.entrySet() ) {
|
||||||
|
entityMap.put( DepartmentMapper.INSTANCE.toSecretaryEntity( dtoEntry.getKey() ) ,
|
||||||
|
DepartmentMapper.INSTANCE.toEmployeeEntity( dtoEntry.getValue() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
package org.mapstruct.ap.test.updatemethods.selection;
|
package org.mapstruct.ap.test.updatemethods.selection;
|
||||||
|
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.MappingTarget;
|
import org.mapstruct.MappingTarget;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
import org.mapstruct.ap.test.updatemethods.DepartmentDto;
|
import org.mapstruct.ap.test.updatemethods.DepartmentDto;
|
||||||
import org.mapstruct.ap.test.updatemethods.DepartmentEntity;
|
import org.mapstruct.ap.test.updatemethods.DepartmentEntity;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
@ -33,6 +35,10 @@ public interface ExternalMapper {
|
|||||||
|
|
||||||
ExternalMapper INSTANCE = Mappers.getMapper( ExternalMapper.class );
|
ExternalMapper INSTANCE = Mappers.getMapper( ExternalMapper.class );
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping( target = "employees", ignore = true ),
|
||||||
|
@Mapping( target = "secretaryToEmployee", ignore = true )
|
||||||
|
})
|
||||||
void toDepartmentEntity(DepartmentDto dto, @MappingTarget DepartmentEntity entity);
|
void toDepartmentEntity(DepartmentDto dto, @MappingTarget DepartmentEntity entity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.test.updatemethods.selection;
|
package org.mapstruct.ap.test.updatemethods.selection;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mapstruct.ap.test.updatemethods.CompanyDto;
|
import org.mapstruct.ap.test.updatemethods.CompanyDto;
|
||||||
@ -25,6 +29,10 @@ import org.mapstruct.ap.test.updatemethods.CompanyEntity;
|
|||||||
import org.mapstruct.ap.test.updatemethods.DepartmentDto;
|
import org.mapstruct.ap.test.updatemethods.DepartmentDto;
|
||||||
import org.mapstruct.ap.test.updatemethods.DepartmentEntity;
|
import org.mapstruct.ap.test.updatemethods.DepartmentEntity;
|
||||||
import org.mapstruct.ap.test.updatemethods.DepartmentEntityFactory;
|
import org.mapstruct.ap.test.updatemethods.DepartmentEntityFactory;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.EmployeeDto;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.EmployeeEntity;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.SecretaryDto;
|
||||||
|
import org.mapstruct.ap.test.updatemethods.SecretaryEntity;
|
||||||
import org.mapstruct.ap.testutil.IssueKey;
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
import org.mapstruct.ap.testutil.WithClasses;
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
@ -35,17 +43,26 @@ import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
|||||||
*/
|
*/
|
||||||
@IssueKey("160")
|
@IssueKey("160")
|
||||||
@RunWith(AnnotationProcessorTestRunner.class)
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
@WithClasses({
|
||||||
|
OrganizationMapper1.class,
|
||||||
|
ExternalMapper.class,
|
||||||
|
ExternalHandWrittenMapper.class,
|
||||||
|
CompanyDto.class,
|
||||||
|
CompanyEntity.class,
|
||||||
|
DepartmentMapper.class,
|
||||||
|
DepartmentDto.class,
|
||||||
|
DepartmentEntityFactory.class,
|
||||||
|
DepartmentEntity.class,
|
||||||
|
EmployeeDto.class,
|
||||||
|
EmployeeEntity.class,
|
||||||
|
SecretaryDto.class,
|
||||||
|
SecretaryEntity.class
|
||||||
|
})
|
||||||
public class ExternalSelectionTest {
|
public class ExternalSelectionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithClasses({
|
@WithClasses({
|
||||||
OrganizationMapper1.class,
|
OrganizationMapper1.class
|
||||||
ExternalMapper.class,
|
|
||||||
CompanyDto.class,
|
|
||||||
CompanyEntity.class,
|
|
||||||
DepartmentDto.class,
|
|
||||||
DepartmentEntityFactory.class,
|
|
||||||
DepartmentEntity.class
|
|
||||||
})
|
})
|
||||||
public void shouldSelectGeneratedExternalMapper() {
|
public void shouldSelectGeneratedExternalMapper() {
|
||||||
|
|
||||||
@ -56,13 +73,7 @@ public class ExternalSelectionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithClasses({
|
@WithClasses({
|
||||||
OrganizationMapper2.class,
|
OrganizationMapper2.class
|
||||||
ExternalHandWrittenMapper.class,
|
|
||||||
CompanyDto.class,
|
|
||||||
CompanyEntity.class,
|
|
||||||
DepartmentDto.class,
|
|
||||||
DepartmentEntityFactory.class,
|
|
||||||
DepartmentEntity.class
|
|
||||||
})
|
})
|
||||||
public void shouldSelectGeneratedHandWrittenExternalMapper() {
|
public void shouldSelectGeneratedHandWrittenExternalMapper() {
|
||||||
|
|
||||||
@ -71,4 +82,33 @@ public class ExternalSelectionTest {
|
|||||||
OrganizationMapper2.INSTANCE.toCompanyEntity( dto, entity );
|
OrganizationMapper2.INSTANCE.toCompanyEntity( dto, entity );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IssueKey( "487" )
|
||||||
|
public void shouldSelectGeneratedExternalMapperForIterablesAndMaps() {
|
||||||
|
|
||||||
|
DepartmentDto departmentDto = new DepartmentDto();
|
||||||
|
EmployeeDto employeeDto = new EmployeeDto();
|
||||||
|
employeeDto.setName( "Sarah" );
|
||||||
|
SecretaryDto secretaryDto = new SecretaryDto();
|
||||||
|
secretaryDto.setName( "Jim" );
|
||||||
|
departmentDto.setEmployees( Arrays.asList( employeeDto ) );
|
||||||
|
Map<SecretaryDto, EmployeeDto> secretaryToEmployee = new HashMap<SecretaryDto, EmployeeDto>();
|
||||||
|
secretaryToEmployee.put( secretaryDto, employeeDto );
|
||||||
|
departmentDto.setSecretaryToEmployee( secretaryToEmployee );
|
||||||
|
|
||||||
|
DepartmentEntity departmentEntity = new DepartmentEntity( 5 );
|
||||||
|
|
||||||
|
DepartmentMapper.INSTANCE.toDepartmentEntity( departmentDto, departmentEntity );
|
||||||
|
|
||||||
|
assertThat( departmentEntity ).isNotNull();
|
||||||
|
assertThat( departmentEntity.getEmployees() ).isNotEmpty();
|
||||||
|
assertThat( departmentEntity.getEmployees().get( 0 ).getName() ).isEqualTo( "Sarah" );
|
||||||
|
assertThat( departmentEntity.getSecretaryToEmployee() ).isNotEmpty();
|
||||||
|
Map.Entry<SecretaryEntity, EmployeeEntity> firstEntry =
|
||||||
|
departmentEntity.getSecretaryToEmployee().entrySet().iterator().next();
|
||||||
|
assertThat( firstEntry.getKey().getName() ).isEqualTo( "Jim" );
|
||||||
|
assertThat( firstEntry.getValue().getName() ).isEqualTo( "Sarah" );
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user