use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.
the class QualifierSelector method getQualifierAnnotationMirrors.
private Set<AnnotationMirror> getQualifierAnnotationMirrors(Method candidate) {
// retrieve annotations
Set<AnnotationMirror> qualiferAnnotations = new HashSet<AnnotationMirror>();
// first from the method itself
SourceMethod candidateSM = (SourceMethod) candidate;
List<? extends AnnotationMirror> methodAnnotations = candidateSM.getExecutable().getAnnotationMirrors();
for (AnnotationMirror methodAnnotation : methodAnnotations) {
addOnlyWhenQualifier(qualiferAnnotations, methodAnnotation);
}
// then from the mapper (if declared)
Type mapper = candidate.getDeclaringMapper();
if (mapper != null) {
List<? extends AnnotationMirror> mapperAnnotations = mapper.getTypeElement().getAnnotationMirrors();
for (AnnotationMirror mapperAnnotation : mapperAnnotations) {
addOnlyWhenQualifier(qualiferAnnotations, mapperAnnotation);
}
}
return qualiferAnnotations;
}
use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.
the class QualifierSelector method getMatchingMethods.
@Override
public <T extends Method> List<SelectedMethod<T>> getMatchingMethods(Method mappingMethod, List<SelectedMethod<T>> methods, List<Type> sourceTypes, Type targetType, SelectionCriteria criteria) {
int numberOfQualifiersToMatch = 0;
// Define some local collections and make sure that they are defined.
List<TypeMirror> qualifierTypes = new ArrayList<TypeMirror>();
if (criteria.getQualifiers() != null) {
qualifierTypes.addAll(criteria.getQualifiers());
numberOfQualifiersToMatch += criteria.getQualifiers().size();
}
List<String> qualfiedByNames = new ArrayList<String>();
if (criteria.getQualifiedByNames() != null) {
qualfiedByNames.addAll(criteria.getQualifiedByNames());
numberOfQualifiersToMatch += criteria.getQualifiedByNames().size();
}
// add the mapstruct @Named annotation as annotation to look for
if (!qualfiedByNames.isEmpty()) {
qualifierTypes.add(namedAnnotationTypeMirror);
}
// Check there are qualfiers for this mapping: Mapping#qualifier or Mapping#qualfiedByName
if (qualifierTypes.isEmpty()) {
// When no qualifiers, disqualify all methods marked with a qualifier by removing them from the candidates
List<SelectedMethod<T>> nonQualiferAnnotatedMethods = new ArrayList<SelectedMethod<T>>(methods.size());
for (SelectedMethod<T> candidate : methods) {
if (candidate.getMethod() instanceof SourceMethod) {
Set<AnnotationMirror> qualifierAnnotations = getQualifierAnnotationMirrors(candidate.getMethod());
if (qualifierAnnotations.isEmpty()) {
nonQualiferAnnotatedMethods.add(candidate);
}
} else {
nonQualiferAnnotatedMethods.add(candidate);
}
}
return nonQualiferAnnotatedMethods;
} else {
// Check all methods marked with qualfier (or methods in Mappers marked wiht a qualfier) for matches.
List<SelectedMethod<T>> matches = new ArrayList<SelectedMethod<T>>(methods.size());
for (SelectedMethod<T> candidate : methods) {
if (!(candidate.getMethod() instanceof SourceMethod)) {
continue;
}
// retrieve annotations
Set<AnnotationMirror> qualifierAnnotationMirrors = getQualifierAnnotationMirrors(candidate.getMethod());
// now count if all qualifiers are matched
int matchingQualifierCounter = 0;
for (AnnotationMirror qualifierAnnotationMirror : qualifierAnnotationMirrors) {
for (TypeMirror qualifierType : qualifierTypes) {
// get the type of the annotation mirror.
DeclaredType qualifierAnnotationType = qualifierAnnotationMirror.getAnnotationType();
if (typeUtils.isSameType(qualifierType, qualifierAnnotationType)) {
// Match! we have an annotation which has the @Qualifer marker ( could be @Named as well )
if (typeUtils.isSameType(qualifierAnnotationType, namedAnnotationTypeMirror)) {
// Match! its an @Named, so do the additional check on name.
NamedPrism namedPrism = NamedPrism.getInstance(qualifierAnnotationMirror);
if (namedPrism.value() != null && qualfiedByNames.contains(namedPrism.value())) {
// Match! its an @Name and the value matches as well. Oh boy.
matchingQualifierCounter++;
}
} else {
// Match! its a self declared qualifer annoation (marked with @Qualifier)
matchingQualifierCounter++;
}
break;
}
}
}
if (matchingQualifierCounter == numberOfQualifiersToMatch) {
// Only if all qualifiers are matched with a qualifying annotation, add candidate
matches.add(candidate);
}
}
if (!matches.isEmpty()) {
return matches;
} else {
return methods;
}
}
}
use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.
the class MapperCreationProcessor method reportErrorWhenAmbigousReverseMapping.
private void reportErrorWhenAmbigousReverseMapping(List<SourceMethod> candidates, SourceMethod method, InheritInverseConfigurationPrism reversePrism) {
List<String> candidateNames = new ArrayList<String>();
for (SourceMethod candidate : candidates) {
candidateNames.add(candidate.getName());
}
String name = reversePrism.name();
if (name.isEmpty()) {
messager.printMessage(method.getExecutable(), reversePrism.mirror, Message.INHERITINVERSECONFIGURATION_DUPLICATES, Strings.join(candidateNames, "(), "));
} else {
messager.printMessage(method.getExecutable(), reversePrism.mirror, Message.INHERITINVERSECONFIGURATION_INVALID_NAME, Strings.join(candidateNames, "(), "), name);
}
}
use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.
the class MapperCreationProcessor method getMappingMethods.
private List<MappingMethod> getMappingMethods(MapperConfiguration mapperConfig, List<SourceMethod> methods) {
List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>();
for (SourceMethod method : methods) {
if (!method.overridesMethod()) {
continue;
}
mergeInheritedOptions(method, mapperConfig, methods, new ArrayList<SourceMethod>());
MappingOptions mappingOptions = method.getMappingOptions();
boolean hasFactoryMethod = false;
if (method.isIterableMapping()) {
IterableMappingMethod iterableMappingMethod = createWithElementMappingMethod(method, mappingOptions, new IterableMappingMethod.Builder());
hasFactoryMethod = iterableMappingMethod.getFactoryMethod() != null;
mappingMethods.add(iterableMappingMethod);
} else if (method.isMapMapping()) {
MapMappingMethod.Builder builder = new MapMappingMethod.Builder();
SelectionParameters keySelectionParameters = null;
FormattingParameters keyFormattingParameters = null;
SelectionParameters valueSelectionParameters = null;
FormattingParameters valueFormattingParameters = null;
NullValueMappingStrategyPrism nullValueMappingStrategy = null;
if (mappingOptions.getMapMapping() != null) {
keySelectionParameters = mappingOptions.getMapMapping().getKeySelectionParameters();
keyFormattingParameters = mappingOptions.getMapMapping().getKeyFormattingParameters();
valueSelectionParameters = mappingOptions.getMapMapping().getValueSelectionParameters();
valueFormattingParameters = mappingOptions.getMapMapping().getValueFormattingParameters();
nullValueMappingStrategy = mappingOptions.getMapMapping().getNullValueMappingStrategy();
}
MapMappingMethod mapMappingMethod = builder.mappingContext(mappingContext).method(method).keyFormattingParameters(keyFormattingParameters).keySelectionParameters(keySelectionParameters).valueFormattingParameters(valueFormattingParameters).valueSelectionParameters(valueSelectionParameters).nullValueMappingStrategy(nullValueMappingStrategy).build();
hasFactoryMethod = mapMappingMethod.getFactoryMethod() != null;
mappingMethods.add(mapMappingMethod);
} else if (method.isValueMapping()) {
// prefer value mappings over enum mapping
ValueMappingMethod valueMappingMethod = new ValueMappingMethod.Builder().mappingContext(mappingContext).method(method).valueMappings(mappingOptions.getValueMappings()).build();
mappingMethods.add(valueMappingMethod);
} else if (method.isEnumMapping()) {
messager.printMessage(method.getExecutable(), Message.ENUMMAPPING_DEPRECATED);
EnumMappingMethod.Builder builder = new EnumMappingMethod.Builder();
MappingMethod enumMappingMethod = builder.mappingContext(mappingContext).souceMethod(method).build();
if (enumMappingMethod != null) {
mappingMethods.add(enumMappingMethod);
}
} else if (method.isStreamMapping()) {
StreamMappingMethod streamMappingMethod = createWithElementMappingMethod(method, mappingOptions, new StreamMappingMethod.Builder());
// If we do StreamMapping that means that internally there is a way to generate the result type
hasFactoryMethod = streamMappingMethod.getFactoryMethod() != null || method.getResultType().isStreamType();
mappingMethods.add(streamMappingMethod);
} else {
NullValueMappingStrategyPrism nullValueMappingStrategy = null;
SelectionParameters selectionParameters = null;
if (mappingOptions.getBeanMapping() != null) {
nullValueMappingStrategy = mappingOptions.getBeanMapping().getNullValueMappingStrategy();
selectionParameters = mappingOptions.getBeanMapping().getSelectionParameters();
}
BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder();
BeanMappingMethod beanMappingMethod = builder.mappingContext(mappingContext).souceMethod(method).nullValueMappingStrategy(nullValueMappingStrategy).selectionParameters(selectionParameters).build();
if (beanMappingMethod != null) {
// We can consider that the bean mapping method can always be constructed. If there is a problem
// it would have been reported in its build
hasFactoryMethod = true;
mappingMethods.add(beanMappingMethod);
}
}
if (!hasFactoryMethod) {
// A factory method is allowed to return an interface type and hence, the generated
// implementation as well. The check below must only be executed if there's no factory
// method that could be responsible.
reportErrorIfNoImplementationTypeIsRegisteredForInterfaceReturnType(method);
}
}
return mappingMethods;
}
use of org.mapstruct.ap.internal.model.source.SourceMethod in project mapstruct by mapstruct.
the class MapperCreationProcessor method reportErrorWhenAmbigousMapping.
private void reportErrorWhenAmbigousMapping(List<SourceMethod> candidates, SourceMethod method, InheritConfigurationPrism prism) {
List<String> candidateNames = new ArrayList<String>();
for (SourceMethod candidate : candidates) {
candidateNames.add(candidate.getName());
}
String name = prism.name();
if (name.isEmpty()) {
messager.printMessage(method.getExecutable(), prism.mirror, Message.INHERITCONFIGURATION_DUPLICATES, Strings.join(candidateNames, "(), "));
} else {
messager.printMessage(method.getExecutable(), prism.mirror, Message.INHERITCONFIGURATION_INVALIDNAME, Strings.join(candidateNames, "(), "), name);
}
}
Aggregations