Class NestedTargetPropertyMappingHolder.Builder

    • Field Detail

      • method

        private Method method
      • existingVariableNames

        private java.util.Set<java.lang.String> existingVariableNames
      • propertyMappings

        private java.util.List<PropertyMapping> propertyMappings
      • handledTargets

        private java.util.Set<java.lang.String> handledTargets
      • targetPropertiesWriteAccessors

        private java.util.Map<java.lang.String,​Accessor> targetPropertiesWriteAccessors
      • targetType

        private Type targetType
      • errorOccurred

        private boolean errorOccurred
    • Constructor Detail

      • Builder

        public Builder()
    • Method Detail

      • handleSourceParameterMappings

        private void handleSourceParameterMappings​(java.util.Set<MappingReference> sourceParameterMappings,
                                                   java.lang.String targetProperty,
                                                   Parameter sourceParameter,
                                                   boolean forceUpdateMethod)
        Handle the PropertyMapping creation for source parameter mappings.
        Parameters:
        sourceParameterMappings - the source parameter mappings for which property mapping should be done
        targetProperty - the target property that is being mapped
        sourceParameter - the source parameter that is used
        forceUpdateMethod - whether we need to force an update method
      • groupByTargetReferences

        private NestedTargetPropertyMappingHolder.GroupedTargetReferences groupByTargetReferences()
        The target references are popped. The List<MappingOptions> are keyed on the unique first entries of the target references.

        Group all target references by their first property and for each such mapping use a new one where the first property will be removed from it. If a Mapping cannot be popped, i.e. it contains a non nested target property just keep it as is (this is usually needed to control how an intermediary level can be mapped).

        We start with the following mappings:

         @Mapping(target = "fish.kind", source = "fish.type"),
         @Mapping(target = "fish.name", ignore = true),
         @Mapping(target = "ornament", ignore = true ),
         @Mapping(target = "material.materialType", source = "material"),
         @Mapping(target = "document", source = "report"),
         @Mapping(target = "document.organisation.name", source = "report.organisationName")
         
        We will get this:
         // All target references are popped and grouped by their first property
         GroupedTargetReferences.poppedTargetReferences {
             fish:     @Mapping(target = "kind", source = "fish.type"),
                       @Mapping(target = "name", ignore = true);
             material: @Mapping(target = "materialType", source = "material");
             document: @Mapping(target = "organization.name", source = "report.organizationName");
         }
        
         //This references are not nested and we they stay as they were
         GroupedTargetReferences.singleTargetReferences {
             document: @Mapping(target = "document", source = "report");
             ornament: @Mapping(target = "ornament", ignore = true );
         }
         
        Returns:
        See above
      • groupBySourceParameter

        private NestedTargetPropertyMappingHolder.GroupedBySourceParameters groupBySourceParameter​(java.util.Set<MappingReference> mappings,
                                                                                                   java.util.Set<MappingReference> singleTargetReferences)
        Splits the List of Mappings into possibly more Mappings based on each source method parameter type. Note: this method is used for forging nested update methods. For that purpose, the same method with all joined mappings should be generated. See also: NestedTargetPropertiesTest#shouldMapNestedComposedTarget Mappings:
         @Mapping(target = "organization.name", source = "report.organizationName");
         
        singleTargetReferences:
         @Mapping(target = "document", source = "report");
         
        We assume that all properties belong to the same source parameter (fish). We are getting this in return:
         GroupedBySourceParameters.groupedBySourceParameter {
             fish: @Mapping(target = "organization.name", source = "report.organizationName");
         }
        
         GroupedBySourceParameters.notProcessedAppliesToAll {} //empty
        
         
        Notice how the singleTargetReferences are missing. They are used for situations when there are mappings without source. Such as: Mappings:
         @Mapping(target = "organization.name", expression="java(\"Dunno\")");
         
        singleTargetReferences:
         @Mapping(target = "document", source = "report");
         
        The mappings have no source reference so we cannot extract the source parameter from them. When mappings have no source properties then we apply those to all of them. In this case we have a single target reference that can provide a source parameter. So we will get:
         GroupedBySourceParameters.groupedBySourceParameter {
             fish: @Mapping(target = "organization.name", expression="java(\"Dunno\")");
         }
        
         GroupedBySourceParameters.notProcessedAppliesToAll {} //empty
         

        See also how the singleTargetReferences are not part of the mappings. They are used only to make sure that their source parameter is taken into consideration in the next step.

        The notProcessedAppliesToAll contains all Mappings that should have been applied to all but have not because there were no other mappings that we could have used to pass them along. These Mapping(s) are used later on for normal mapping.

        If we only had:

         @Mapping(target = "document", source = "report");
         @Mapping(target = "ornament", ignore = true );
         
        Then we only would have had:
         GroupedBySourceParameters.notProcessedAppliesToAll {
         @Mapping(target = "document", source = "report");
         @Mapping(target = "ornament", ignore = true );
         }
         
        These mappings will be part of the GroupedBySourceParameters.notProcessedAppliesToAll and are used to be passed to the normal defined mapping.
        Parameters:
        mappings - that mappings that need to be used for the grouping
        singleTargetReferences - a List containing all non-nested mappings for the same grouped target property as the mappings
        Returns:
        the split mapping options.
      • groupByPoppedSourceReferences

        private NestedTargetPropertyMappingHolder.GroupedSourceReferences groupByPoppedSourceReferences​(java.util.Map.Entry<Parameter,​java.util.Set<MappingReference>> entryByParam,
                                                                                                        java.util.Set<MappingReference> singleTargetReferences)
        Creates a nested grouping by popping the source mappings. See the description of the class to see what is generated. Mappings:
         @Mapping(target = "organization.name", source = "report.organizationName");
         
        singleTargetReferences:
         @Mapping(target = "document", source = "report");
         
        And we get:
         GroupedSourceReferences.groupedBySourceReferences {
             report: @Mapping(target = "organization.name", source = "organizationName");
         }
         
        Parameters:
        entryByParam - the entry of a Parameter and it's associated MappingOptions(s) that need to be used for grouping on popped source references
        singleTargetReferences - the single target references that match the source mappings
        Returns:
        the Grouped Source References
      • extractSingleTargetReferencesToUseAndPopulateSourceParameterMappings

        private java.util.Set<MappingReference> extractSingleTargetReferencesToUseAndPopulateSourceParameterMappings​(java.util.Set<MappingReference> singleTargetReferences,
                                                                                                                     java.util.Set<MappingReference> sourceParameterMappings,
                                                                                                                     boolean hasNoMappings,
                                                                                                                     Parameter sourceParameter)
        Extracts all relevant single target references and populates the sourceParameterMappings if needed. A relevant single target reference mapping is a mapping that has a valid source reference and is for the sourceParameter. If there are no mappings i.e. hasNoMappings = true and the source reference in the mapping has no property entries then add that to the sourceParameterMappings (mappings like this have found themselves here because there is a mapping method with multiple parameters and that are using the same sub-path in the target properties).
        Parameters:
        singleTargetReferences - All the single target references for a target property
        sourceParameterMappings - a List that needs to be populated with valid mappings when hasNoMappings = true and there are no property entries in the source reference
        hasNoMappings - parameter indicating whether there were any extracted mappings for this target property
        sourceParameter - the source parameter for which the grouping is being done
        Returns:
        a list with valid single target references
      • createPropertyMappingForNestedTarget

        private PropertyMapping createPropertyMappingForNestedTarget​(MappingReferences mappingReferences,
                                                                     java.lang.String targetPropertyName,
                                                                     SourceReference sourceReference,
                                                                     boolean forceUpdateMethod)
      • populateWithSingleTargetReferences

        private <K> void populateWithSingleTargetReferences​(java.util.Map<K,​java.util.Set<MappingReference>> map,
                                                            java.util.Set<MappingReference> singleTargetReferences,
                                                            java.util.function.Function<SourceReference,​K> keyExtractor)
        If a single target mapping has a valid SourceReference and the SourceReference has more then 0 PropertyEntry and if the map does not contain an entry with the extracted key then an entry with the extracted key and an empty list is added.
        Parameters:
        map - that needs to be populated
        singleTargetReferences - to use
        keyExtractor - to be used to extract a key