/** * 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.internal.util; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; import org.mapstruct.ap.internal.option.Options; import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism; import org.mapstruct.ap.internal.prism.MapperConfigPrism; import org.mapstruct.ap.internal.prism.MapperPrism; import org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism; import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism; import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; import org.mapstruct.ap.internal.prism.ReportingPolicyPrism; /** * Provides an aggregated view to the settings given via {@link org.mapstruct.Mapper} and * {@link org.mapstruct.MapperConfig} for a specific mapper class. * <p> * Settings given via {@code Mapper} will generally take precedence over settings inherited from a referenced config * class. The lists of referenced mappers given via {@link org.mapstruct.Mapper#uses()} and * {@link org.mapstruct.MapperConfig#uses() } will be merged. * * @author Sjaak Derksen */ public class MapperConfiguration { private final MapperPrism mapperPrism; private final MapperConfigPrism mapperConfigPrism; private final DeclaredType config; public static MapperConfiguration getInstanceOn(Element e) { return new MapperConfiguration( MapperPrism.getInstanceOn( e ) ); } private MapperConfiguration(MapperPrism mapperPrism) { this.mapperPrism = mapperPrism; if ( mapperPrism.values.config() != null ) { // TODO #737 Only a declared type makes sense here; Validate and raise graceful error; // Also validate that @MapperConfig is present this.config = (DeclaredType) mapperPrism.config(); this.mapperConfigPrism = MapperConfigPrism.getInstanceOn( config.asElement() ); } else { this.config = null; this.mapperConfigPrism = null; } } public String implementationName() { if ( mapperConfigPrism != null && mapperPrism.values.implementationName() == null ) { return mapperConfigPrism.implementationName(); } else { return mapperPrism.implementationName(); } } public String implementationPackage() { if ( mapperConfigPrism != null && mapperPrism.values.implementationPackage() == null ) { return mapperConfigPrism.implementationPackage(); } else { return mapperPrism.implementationPackage(); } } public Set<DeclaredType> uses() { Set<DeclaredType> uses = new LinkedHashSet<DeclaredType>(); for ( TypeMirror usedMapperType : mapperPrism.uses() ) { // TODO #737 Only declared type make sense here; Validate and raise graceful error; uses.add( (DeclaredType) usedMapperType ); } if ( mapperConfigPrism != null ) { for ( TypeMirror usedMapperType : mapperConfigPrism.uses() ) { // TODO #737 Only declared type make sense here; Validate and raise graceful error; uses.add( (DeclaredType) usedMapperType ); } } return uses; } public List<TypeMirror> imports() { return mapperPrism.imports(); } public ReportingPolicyPrism unmappedTargetPolicy(Options options) { if ( mapperPrism.values.unmappedTargetPolicy() != null ) { return ReportingPolicyPrism.valueOf( mapperPrism.unmappedTargetPolicy() ); } if ( mapperConfigPrism != null && mapperConfigPrism.values.unmappedTargetPolicy() != null ) { return ReportingPolicyPrism.valueOf( mapperConfigPrism.unmappedTargetPolicy() ); } if ( options.getUnmappedTargetPolicy() != null ) { return options.getUnmappedTargetPolicy(); } // fall back to default defined in the annotation return ReportingPolicyPrism.valueOf( mapperPrism.unmappedTargetPolicy() ); } public CollectionMappingStrategyPrism getCollectionMappingStrategy() { if ( mapperConfigPrism != null && mapperPrism.values.collectionMappingStrategy() == null ) { return CollectionMappingStrategyPrism.valueOf( mapperConfigPrism.collectionMappingStrategy() ); } else { return CollectionMappingStrategyPrism.valueOf( mapperPrism.collectionMappingStrategy() ); } } public MappingInheritanceStrategyPrism getMappingInheritanceStrategy() { if ( mapperConfigPrism != null && mapperPrism.values.mappingInheritanceStrategy() == null ) { return MappingInheritanceStrategyPrism.valueOf( mapperConfigPrism.mappingInheritanceStrategy() ); } else { return MappingInheritanceStrategyPrism.valueOf( mapperPrism.mappingInheritanceStrategy() ); } } public NullValueCheckStrategyPrism getNullValueCheckStrategy() { if ( mapperConfigPrism != null && mapperPrism.values.nullValueCheckStrategy() == null ) { return NullValueCheckStrategyPrism.valueOf( mapperConfigPrism.nullValueCheckStrategy() ); } else { return NullValueCheckStrategyPrism.valueOf( mapperPrism.nullValueCheckStrategy() ); } } public boolean isMapToDefault(NullValueMappingStrategyPrism mapNullToDefault) { // check on method level if ( mapNullToDefault != null ) { return mapNullToDefault == NullValueMappingStrategyPrism.RETURN_DEFAULT; } return isMapToDefaultOnMapperAndMappingConfigLevel(); } private boolean isMapToDefaultOnMapperAndMappingConfigLevel() { final NullValueMappingStrategyPrism strategy; if ( mapperConfigPrism != null && mapperPrism.values.nullValueMappingStrategy() == null ) { strategy = NullValueMappingStrategyPrism.valueOf( mapperConfigPrism.nullValueMappingStrategy() ); } else { strategy = NullValueMappingStrategyPrism.valueOf( mapperPrism.nullValueMappingStrategy() ); } return NullValueMappingStrategyPrism.RETURN_DEFAULT == strategy; } public String componentModel(Options options) { if ( mapperPrism.values.componentModel() != null ) { return mapperPrism.componentModel(); } if ( mapperConfigPrism != null && mapperConfigPrism.values.componentModel() != null ) { return mapperConfigPrism.componentModel(); } if ( options.getDefaultComponentModel() != null ) { return options.getDefaultComponentModel(); } return mapperPrism.componentModel(); // fall back to default defined in the annotation } public boolean isDisableSubMappingMethodsGeneration() { if ( mapperPrism.disableSubMappingMethodsGeneration() ) { return mapperPrism.disableSubMappingMethodsGeneration(); } if ( mapperConfigPrism != null && mapperConfigPrism.disableSubMappingMethodsGeneration() ) { return mapperConfigPrism.disableSubMappingMethodsGeneration(); } return mapperPrism.disableSubMappingMethodsGeneration(); // fall back to default defined in the annotation } public DeclaredType config() { return config; } public boolean isValid() { return mapperPrism.isValid; } public AnnotationMirror getAnnotationMirror() { return mapperPrism.mirror; } }