mapstruct / mapstruct/mapstruct-spring-extensions

Allow inherited DelegatingConverter to be processed

Open
#104 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
181
Forks
33
Avg merge
2d 18h
Merged PRs (30d)
3

Description

Related to https://github.com/mapstruct/mapstruct-spring-extensions/issues/101

Hi,

I am trying to modify the annotation processor to support custom Converter interface but I don't know how to process DelegatingConverter by inheritance.

New code in `ConverterMapperProcessor`:
```java
delegatingConverterDescriptors =
annotations.stream()
.filter(ConverterMapperProcessor::isDelegatingConverterAnnotation)
.map(roundEnv::getElementsAnnotatedWith)
.flatMap(Set::stream)
.map(ExecutableElement.class::cast)
// Do not generate delegate without Mapper annotation on class
.filter(annotatedMethod -> annotatedMethod.getEnclosingElement().getAnnotationMirrors().stream().anyMatch(x -> x.getAnnotationType().toString().equals(MAPPER)))
.map(annotatedMethod -> new DelegatingConverterDescriptor(annotatedMethod, processingEnv))
.collect(toList());
```

Custom converter:
```java
public interface BaseMapper extends Converter {

@Nullable
T convert(@NonNull S source, @Context CycleAvoidingMappingContext context);

@Nullable
@Override
@Named("baseConvert")
default T convert(@NonNull S source) {
return convert(source, new CycleAvoidingMappingContext());
}

// Annotation is not processed
@DelegatingConverter
@InheritInverseConfiguration
default S invertConvert(T source) {
return invertConvert(source, new CycleAvoidingMappingContext());
}

S invertConvert(T source, @Context CycleAvoidingMappingContext context);
}
```

Mapper:
```java
@Mapper(config = MapperConfig.class)
public abstract class CarMapper implements BaseMapper {

// Required annotation to have delegate generated by processor
@DelegatingConverter
@Override
public Car invertConvert(CarDto source) {
return BaseMapper.super.invertConvert(source);
}
}
```

Delegate:
```java
@Component
public class CarDtoToCarConverter implements Converter {
private CarMapper delegateMapper;

public CarDtoToCarConverter(@Autowired final CarMapper delegateMapper) {
this.delegateMapper = delegateMapper;
}

@Override
public Car convert(final CarDto source) {
return delegateMapper.invertConvert(source);
}
}
```

Wanted mapper:
```java
@Mapper(config = MapperConfig.class)
public abstract class CarMapper implements BaseMapper {
// Nothing to override
}
```

Thanks

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in ConverterMapperProcessor and trace how @DelegatingConverter methods are collected from roundEnv; compare that path with the inherited BaseMapper example. Done means the annotation on BaseMapper.invertConvert is recognized for CarMapper without an override and the corresponding delegate is generated.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.