mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
This allows to easily avoid the runtime dependency on mapstruct.jar: we can avoid Mappers.getMapper(...) for instantiating used mappers if the code follows the conventional pattern for creating mapper singletons. Co-authored-by: GIBOU Damien <damien.gibou@biomerieux.com>
This commit is contained in:
parent
aeadf8cb77
commit
c59ca79e7f
@ -21,19 +21,22 @@ import org.mapstruct.ap.internal.util.Strings;
|
||||
*/
|
||||
public class DefaultMapperReference extends MapperReference {
|
||||
|
||||
private final boolean isSingleton;
|
||||
private final boolean isAnnotatedMapper;
|
||||
private final Set<Type> importTypes;
|
||||
|
||||
private DefaultMapperReference(Type type, boolean isAnnotatedMapper, Set<Type> importTypes, String variableName) {
|
||||
private DefaultMapperReference(Type type, boolean isAnnotatedMapper, boolean isSingleton,
|
||||
Set<Type> importTypes, String variableName) {
|
||||
super( type, variableName );
|
||||
this.isAnnotatedMapper = isAnnotatedMapper;
|
||||
this.importTypes = importTypes;
|
||||
this.isSingleton = isSingleton;
|
||||
}
|
||||
|
||||
public static DefaultMapperReference getInstance(Type type, boolean isAnnotatedMapper, TypeFactory typeFactory,
|
||||
List<String> otherMapperReferences) {
|
||||
public static DefaultMapperReference getInstance(Type type, boolean isAnnotatedMapper, boolean isSingleton,
|
||||
TypeFactory typeFactory, List<String> otherMapperReferences) {
|
||||
Set<Type> importTypes = Collections.asSet( type );
|
||||
if ( isAnnotatedMapper ) {
|
||||
if ( isAnnotatedMapper && !isSingleton) {
|
||||
importTypes.add( typeFactory.getType( "org.mapstruct.factory.Mappers" ) );
|
||||
}
|
||||
|
||||
@ -42,7 +45,7 @@ public class DefaultMapperReference extends MapperReference {
|
||||
otherMapperReferences
|
||||
);
|
||||
|
||||
return new DefaultMapperReference( type, isAnnotatedMapper, importTypes, variableName );
|
||||
return new DefaultMapperReference( type, isAnnotatedMapper, isSingleton, importTypes, variableName );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -53,4 +56,9 @@ public class DefaultMapperReference extends MapperReference {
|
||||
public boolean isAnnotatedMapper() {
|
||||
return isAnnotatedMapper;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return isSingleton;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
package org.mapstruct.ap.internal.processor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
@ -13,7 +14,9 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
@ -60,6 +63,9 @@ import org.mapstruct.ap.internal.util.Message;
|
||||
import org.mapstruct.ap.internal.util.Strings;
|
||||
import org.mapstruct.ap.internal.version.VersionInformation;
|
||||
|
||||
import static javax.lang.model.element.Modifier.FINAL;
|
||||
import static javax.lang.model.element.Modifier.PUBLIC;
|
||||
import static javax.lang.model.element.Modifier.STATIC;
|
||||
import static org.mapstruct.ap.internal.model.SupportingConstructorFragment.addAllFragmentsIn;
|
||||
import static org.mapstruct.ap.internal.model.SupportingField.addAllFieldsIn;
|
||||
import static org.mapstruct.ap.internal.util.Collections.first;
|
||||
@ -73,6 +79,9 @@ import static org.mapstruct.ap.internal.util.Collections.join;
|
||||
*/
|
||||
public class MapperCreationProcessor implements ModelElementProcessor<List<SourceMethod>, Mapper> {
|
||||
|
||||
/** Modifiers for public "constant" e.g. "public static final" */
|
||||
private static final List<Modifier> PUBLIC_CONSTANT_MODIFIERS = Arrays.asList( PUBLIC, STATIC, FINAL );
|
||||
|
||||
private ElementUtils elementUtils;
|
||||
private TypeUtils typeUtils;
|
||||
private FormattingMessager messager;
|
||||
@ -136,6 +145,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
DefaultMapperReference mapperReference = DefaultMapperReference.getInstance(
|
||||
typeFactory.getType( usedMapper ),
|
||||
MapperGem.instanceOn( typeUtils.asElement( usedMapper ) ) != null,
|
||||
hasSingletonInstance( usedMapper ),
|
||||
typeFactory,
|
||||
variableNames
|
||||
);
|
||||
@ -147,6 +157,22 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean hasSingletonInstance(TypeMirror mapper) {
|
||||
return typeUtils.asElement( mapper ).getEnclosedElements().stream()
|
||||
.anyMatch( a -> isPublicConstantOfType( a, "INSTANCE", mapper ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the <code>element</code> is a "public static final" field (e.g. a constant)
|
||||
* named <code>fieldName</code> of type "fieldType"
|
||||
*/
|
||||
private boolean isPublicConstantOfType(Element element, String fieldName, TypeMirror fieldType) {
|
||||
return element.getKind().isField() &&
|
||||
element.getModifiers().containsAll( PUBLIC_CONSTANT_MODIFIERS ) &&
|
||||
element.getSimpleName().contentEquals( fieldName ) &&
|
||||
typeUtils.isSameType( element.asType(), fieldType );
|
||||
}
|
||||
|
||||
private Mapper getMapper(TypeElement element, MapperOptions mapperOptions, List<SourceMethod> methods) {
|
||||
|
||||
List<MappingMethod> mappingMethods = getMappingMethods( mapperOptions, methods );
|
||||
|
@ -6,4 +6,4 @@
|
||||
|
||||
-->
|
||||
<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.DefaultMapperReference" -->
|
||||
private final <@includeModel object=type/> ${variableName} = <#if annotatedMapper>Mappers.getMapper( <@includeModel object=type/>.class );<#else>new <@includeModel object=type/>();</#if>
|
||||
private final <@includeModel object=type/> ${variableName} = <#if singleton><@includeModel object=type/>.INSTANCE;<#else><#if annotatedMapper>Mappers.getMapper( <@includeModel object=type/>.class );<#else>new <@includeModel object=type/>();</#if></#if>
|
@ -9,7 +9,6 @@ import javax.annotation.Generated;
|
||||
import org.mapstruct.ap.test.updatemethods.CompanyDto;
|
||||
import org.mapstruct.ap.test.updatemethods.CompanyEntity;
|
||||
import org.mapstruct.ap.test.updatemethods.DepartmentEntityFactory;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Generated(
|
||||
value = "org.mapstruct.ap.MappingProcessor",
|
||||
@ -18,7 +17,7 @@ import org.mapstruct.factory.Mappers;
|
||||
)
|
||||
public class OrganizationMapper1Impl implements OrganizationMapper1 {
|
||||
|
||||
private final ExternalMapper externalMapper = Mappers.getMapper( ExternalMapper.class );
|
||||
private final ExternalMapper externalMapper = ExternalMapper.INSTANCE;
|
||||
private final DepartmentEntityFactory departmentEntityFactory = new DepartmentEntityFactory();
|
||||
|
||||
@Override
|
||||
|
@ -9,7 +9,6 @@ import javax.annotation.Generated;
|
||||
import org.mapstruct.ap.test.updatemethods.BossDto;
|
||||
import org.mapstruct.ap.test.updatemethods.BossEntity;
|
||||
import org.mapstruct.ap.test.updatemethods.ConstructableDepartmentEntity;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Generated(
|
||||
value = "org.mapstruct.ap.MappingProcessor",
|
||||
@ -18,7 +17,7 @@ import org.mapstruct.factory.Mappers;
|
||||
)
|
||||
public class OrganizationMapper3Impl implements OrganizationMapper3 {
|
||||
|
||||
private final ExternalMapper externalMapper = Mappers.getMapper( ExternalMapper.class );
|
||||
private final ExternalMapper externalMapper = ExternalMapper.INSTANCE;
|
||||
|
||||
@Override
|
||||
public void toBossEntity(BossDto dto, BossEntity entity) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user