GeezerVison is showing github.com — Access to the target property name · Issue #2688 · mapstruct/mapstruct
Access to the target property name #2688DescriptionExpose target property to method arguments Reacted by BabkenSahakyan Activityfiliphr commented on Dec 13, 2021 Can you please provide an example? HemalathaGowdar commented on Dec 13, 2021 @Mapper(config = MapperBConfig.class , uses = EValueMapper.class)
@Component
public abstract class AttribMapper {
@Mapping(source = "indicator" , target = "ïndicator")
@Mapping(source = "indicator2" , target = "shellType")
public abstract TargetAttributes TargetAttributesMapper( SourceAttributes src, @MappingTarget TargetAttributes target);
@Condition
public boolean conditioncheck(String value)
{
if(contains in map attribute check) // basically am trying to map to the target attribute if that attribute is required by consumer
return true
else return false
}
}
This method should get invoke for all attributes mapping.
I also tried Conditionexpression to check whether this attribute in teh consumer list to map or not . This also not coming in the generated impl class . I am basically trying for presence check of that attribute in the consumer list. if yes , I should do mapping else ignore mapping part
Could you please suggest here. Zegveld commented on Dec 20, 2021 If I understand correctly what you want is something like I've got a Map<String, Object> named source and another Map<String, Object> named target and I only want to map the entries from source for which there is already an entry present in target?
Trying to do this using conditions with Iterables or Maps is not supported yet, see #1610 for more information.
However writing the mapping yourself might not be that much additional code, and mapstruct can still use it in the mappingchain like this:
@Mapper
public abstract class ConditionalMapMapper {
static class Item {
Map<String, String> value;
// getters and setters
}
static class ItemDto {
Map<String, String> value;
// getters and setters
}
abstract Item map(ItemDto dto, @MappingTarget Item item);
void map(Map<String, String> source, @MappingTarget Map<String, String> target) {
for ( Entry<String, String> entry : source.entrySet() ) {
if ( target.containsKey( entry.getKey() ) ) {
target.put( entry.getKey(), entry.getValue() );
}
}
}
}
The map method with the source and target map will be used in the implementation to map from/to a map.
public class ConditionalMapMapperImpl extends ConditionalMapMapper {
@Override
Item map(ItemDto dto, Item item) {
if ( dto == null ) {
return null;
}
if ( dto.getValue() != null ) {
if ( item.getValue() == null ) {
item.setValue( new LinkedHashMap<String, String>() );
}
map( dto.getValue(), item.getValue() );
}
else {
item.setValue( null );
}
return item;
}
}
Hope this helps. HemalathaGowdar commented on Dec 27, 2021 No , I am looking something if Target attribute name is present in my attribute list(list which has selected target attribute name for each diff scenario ) to map then only i should map else I should skip mapping. Zegveld commented on Dec 27, 2021 So something like:
@Mapper
public abstract class ConditionalMapMapper {
static class Item {
Map<String, String> value;
// getters and setters
}
static class ItemDto {
Map<String, String> value;
// getters and setters
}
abstract Item map(ItemDto dto, @MappingTarget Item item, @Context List<String> attributeList);
void map(Map<String, String> source, @MappingTarget Map<String, String> target, @Context List<String> attributeList) {
for ( Entry<String, String> entry : source.entrySet() ) {
if ( attributeList.contains( entry.getKey() ) ) {
target.put( entry.getKey(), entry.getValue() );
}
}
}
}
The map method with the source and target map will be used in the implementation to map from/to a map.
public class ConditionalMapMapperImpl extends ConditionalMapMapper {
@Override
Item map(ItemDto dto, Item item, List<String> attributeList) {
if ( dto == null ) {
return null;
}
if ( dto.getValue() != null ) {
if ( item.getValue() == null ) {
item.setValue( new LinkedHashMap<String, String>() );
}
map( dto.getValue(), item.getValue(), attributeList );
}
else {
item.setValue( null );
}
return item;
}
}
Am I getting closer or still misunderstanding you? HemalathaGowdar commented on Jan 18, 2022 Sorry for the delay .
This is what we are looking.
package mapstruct;
@Mapper(uses = TesterMapper.PresenceUtill.class)
public interface TesterMapper {
TesterMapper inst = Mappers.getMapper(TesterMapper.class);
@Mapping(source ="name" , target ="name" )
@Mapping(source ="secName" , target ="sName" , conditionExpression = "java(variablePresenceCheck(\"sName\"))" )
@Mapping(source ="isHuman" , target ="isHuman" )
MapsStructTarget mapstrucMapper (MapStructSource src);
class PresenceUtill {
@Condition
public boolean checkmethod(String str , String source)
{
if (null != str)
{
System.out.println(str);
System.out.println(source);
return true;
}
return false;
}
@Condition
public boolean checkmethod(Boolean str)
{
if (null != str)
{
return true;
}
return false;
}
}
default boolean variablePresenceCheck(String str) {
if (I will check this variable name is present in my attrib list ) { return true;
}
return false; }
}
Using conditionExpression I can achieve this , by passing the name of the variable explicitly in conditionExpression.
Do we have something in @condition annotation too - I need the name of the target variable on each mappings. so that I can evaluate whether I need to set this variable or skip Zegveld commented on Jan 18, 2022 @filiphr , I don't believe there is an annotation to reference the property name yet, is there?
So this would be a feature request to implement a method argument annotation much like how @TargetType works for passing the class, perhaps something like @TargetProperty. HemalathaGowdar commented on Jan 18, 2022 Thanks for the information . We can use conditional expression when we have diff names. But when we have the same names for the entire classes , in that case we are not using @mapping annotations.
Could you please suggest for this scenario ? can we achieve this by overriding any of the existing methods for now filiphr commented on Jan 18, 2022 You are right @Zegveld there is no annotation that would allow access to the target property name. Supporting @TargetProperty for a string method argument is something that we could add.
I will rename this issue.
@HemalathaGowdar you can still use @Mapping even if the source and target names are identical.
e.g.
@Mapping(target = "id", conditionExpression = "java(...)")
changed the title [-]Condition annotated method not being invoked in generated IMPL class[/-] [+]Access to the target property name [/+] on Jan 18, 2022filiphr commented on Jan 22, 2022
If you could help me with this new feature timelines
Unfortunately we can't provide timelines, since all of us are working on this on a part time voluntary basis and we try to focus on the most requested features for new releases. In case you are interested in seeing this feature sooner you can always provide a PR that we can review and integrate. BabkenSahakyan commented on Feb 20, 2022 This is exactly the problem I'm facing now. In my case for a given class I've a list of non editable properties which is configurable and may change at runtime and this @Condition methods seems the only appropriate place to do this checking. With a support of @MappingTarget and @TargetProperty problem will be nicely solved.
Thank you all. HemalathaGowdar commented on Mar 4, 2022 When am giving conditional Expression , the NULL check (Null value check strategy) is getting replaced by conditional expression method. I need NULL check too irrespective of conditionalExpression. Could u please suggest filiphr commented on Mar 6, 2022 @HemalathaGowdar please do not use this issue to ask questions about unrelated things. The documentation for this is in the Conditional Mapping section of our documentation. If something is not clear please open a discussion, ask on StackOverflow or out Gitter Room. filiphr commented on Aug 1, 2022 Thanks for your work on this @ivlcic. This has been integrated into main. Reacted by BabkenSahakyan FlorianCassayre commented on Nov 11, 2022 This seems to correspond to what our project is needing. Is there a planned date for the release of 1.6.0 (even a release candidate)? filiphr commented on Nov 12, 2022 @FlorianCassayre we have some other issues that we would like to tackle before we release a first beta release for 1.6. I hope that I can speed this up FlorianCassayre commented on Nov 12, 2022 Thanks for the reply, I understand; we will follow that closely and will be looking forward to that beta release. ivlcic commented on May 16, 2023 Hi guys how's 1.6.0 progressing? filiphr commented on May 20, 2023 @ivlcic it is going slower that I would like. Unfortunately I do not have ample of time, so trying to find the time to wrap things up and do an initial release
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|