All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.linpeilie.processor.gem.AutoMapperGem Maven / Gradle / Ivy

The newest version!
package io.github.linpeilie.processor.gem;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.AbstractAnnotationValueVisitor8;
import javax.lang.model.util.ElementFilter;
import org.mapstruct.tools.gem.Gem;
import org.mapstruct.tools.gem.GemValue;

import javax.lang.model.type.TypeMirror;

public class AutoMapperGem implements Gem {

    private final GemValue target;
    private final GemValue> uses;
    private final GemValue> useEnums;
    private final GemValue> imports;
    private final GemValue convertGenerate;
    private final GemValue mapperName;
    private final GemValue mapperNameSuffix;
    private final GemValue reverseConvertGenerate;
    private final GemValue cycleAvoiding;
    private final GemValue unmappedSourcePolicy;
    private final GemValue unmappedTargetPolicy;
    private final GemValue typeConversionPolicy;
    private final GemValue collectionMappingStrategy;
    private final GemValue nullValueMappingStrategy;
    private final GemValue nullValueIterableMappingStrategy;
    private final GemValue nullValuePropertyMappingStrategy;
    private final GemValue nullValueCheckStrategy;
    private final GemValue mappingControl;
    private final boolean isValid;
    private final AnnotationMirror mirror;

    private AutoMapperGem( BuilderImpl builder ) {
        this.target = builder.target;
        this.uses = builder.uses;
        this.useEnums = builder.useEnums;
        this.imports = builder.imports;
        this.convertGenerate = builder.convertGenerate;
        this.mapperName = builder.mapperName;
        this.mapperNameSuffix = builder.mapperNameSuffix;
        this.reverseConvertGenerate = builder.reverseConvertGenerate;
        this.cycleAvoiding = builder.cycleAvoiding;
        this.unmappedSourcePolicy = builder.unmappedSourcePolicy;
        this.unmappedTargetPolicy = builder.unmappedTargetPolicy;
        this.typeConversionPolicy = builder.typeConversionPolicy;
        this.collectionMappingStrategy = builder.collectionMappingStrategy;
        this.nullValueMappingStrategy = builder.nullValueMappingStrategy;
        this.nullValueIterableMappingStrategy = builder.nullValueIterableMappingStrategy;
        this.nullValuePropertyMappingStrategy = builder.nullValuePropertyMappingStrategy;
        this.nullValueCheckStrategy = builder.nullValueCheckStrategy;
        this.mappingControl = builder.mappingControl;
        isValid = ( this.target != null ? this.target.isValid() : false )
               && ( this.uses != null ? this.uses.isValid() : false )
               && ( this.useEnums != null ? this.useEnums.isValid() : false )
               && ( this.imports != null ? this.imports.isValid() : false )
               && ( this.convertGenerate != null ? this.convertGenerate.isValid() : false )
               && ( this.mapperName != null ? this.mapperName.isValid() : false )
               && ( this.mapperNameSuffix != null ? this.mapperNameSuffix.isValid() : false )
               && ( this.reverseConvertGenerate != null ? this.reverseConvertGenerate.isValid() : false )
               && ( this.cycleAvoiding != null ? this.cycleAvoiding.isValid() : false )
               && ( this.unmappedSourcePolicy != null ? this.unmappedSourcePolicy.isValid() : false )
               && ( this.unmappedTargetPolicy != null ? this.unmappedTargetPolicy.isValid() : false )
               && ( this.typeConversionPolicy != null ? this.typeConversionPolicy.isValid() : false )
               && ( this.collectionMappingStrategy != null ? this.collectionMappingStrategy.isValid() : false )
               && ( this.nullValueMappingStrategy != null ? this.nullValueMappingStrategy.isValid() : false )
               && ( this.nullValueIterableMappingStrategy != null ? this.nullValueIterableMappingStrategy.isValid() : false )
               && ( this.nullValuePropertyMappingStrategy != null ? this.nullValuePropertyMappingStrategy.isValid() : false )
               && ( this.nullValueCheckStrategy != null ? this.nullValueCheckStrategy.isValid() : false )
               && ( this.mappingControl != null ? this.mappingControl.isValid() : false );
        mirror = builder.mirror;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#target}
    */
    public GemValue target( ) {
        return target;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#uses}
    */
    public GemValue> uses( ) {
        return uses;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#useEnums}
    */
    public GemValue> useEnums( ) {
        return useEnums;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#imports}
    */
    public GemValue> imports( ) {
        return imports;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#convertGenerate}
    */
    public GemValue convertGenerate( ) {
        return convertGenerate;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#mapperName}
    */
    public GemValue mapperName( ) {
        return mapperName;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#mapperNameSuffix}
    */
    public GemValue mapperNameSuffix( ) {
        return mapperNameSuffix;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#reverseConvertGenerate}
    */
    public GemValue reverseConvertGenerate( ) {
        return reverseConvertGenerate;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#cycleAvoiding}
    */
    public GemValue cycleAvoiding( ) {
        return cycleAvoiding;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#unmappedSourcePolicy}
    */
    public GemValue unmappedSourcePolicy( ) {
        return unmappedSourcePolicy;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#unmappedTargetPolicy}
    */
    public GemValue unmappedTargetPolicy( ) {
        return unmappedTargetPolicy;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#typeConversionPolicy}
    */
    public GemValue typeConversionPolicy( ) {
        return typeConversionPolicy;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#collectionMappingStrategy}
    */
    public GemValue collectionMappingStrategy( ) {
        return collectionMappingStrategy;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#nullValueMappingStrategy}
    */
    public GemValue nullValueMappingStrategy( ) {
        return nullValueMappingStrategy;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#nullValueIterableMappingStrategy}
    */
    public GemValue nullValueIterableMappingStrategy( ) {
        return nullValueIterableMappingStrategy;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#nullValuePropertyMappingStrategy}
    */
    public GemValue nullValuePropertyMappingStrategy( ) {
        return nullValuePropertyMappingStrategy;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#nullValueCheckStrategy}
    */
    public GemValue nullValueCheckStrategy( ) {
        return nullValueCheckStrategy;
    }

    /**
    * accessor
    *
    * @return the {@link GemValue} for {@link AutoMapperGem#mappingControl}
    */
    public GemValue mappingControl( ) {
        return mappingControl;
    }

    @Override
    public AnnotationMirror mirror( ) {
        return mirror;
    }

    @Override
    public boolean isValid( ) {
        return isValid;
    }

    public static AutoMapperGem  instanceOn(Element element) {
        return build( element, new BuilderImpl() );
    }

    public static AutoMapperGem instanceOn(AnnotationMirror mirror ) {
        return build( mirror, new BuilderImpl() );
    }

    public static   T  build(Element element, Builder builder) {
        AnnotationMirror mirror = element.getAnnotationMirrors().stream()
            .filter( a ->  "io.github.linpeilie.annotations.AutoMapper".contentEquals( ( ( TypeElement )a.getAnnotationType().asElement() ).getQualifiedName() ) )
            .findAny()
            .orElse( null );
        return build( mirror, builder );
    }

    public static  T build(AnnotationMirror mirror, Builder builder ) {

        // return fast
        if ( mirror == null || builder == null ) {
            return null;
        }

        // fetch defaults from all defined values in the annotation type
        List enclosed = ElementFilter.methodsIn( mirror.getAnnotationType().asElement().getEnclosedElements() );
        Map defaultValues = new HashMap<>( enclosed.size() );
        enclosed.forEach( e -> defaultValues.put( e.getSimpleName().toString(), e.getDefaultValue() ) );

        // fetch all explicitely set annotation values in the annotation instance
        Map values = new HashMap<>( enclosed.size() );
        mirror.getElementValues().entrySet().forEach( e -> values.put( e.getKey().getSimpleName().toString(), e.getValue() ) );

        // iterate and populate builder
        for ( String methodName : defaultValues.keySet() ) {

            if ( "target".equals( methodName ) ) {
                builder.setTarget( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), TypeMirror.class ) );
            }
            else if ( "uses".equals( methodName ) ) {
                builder.setUses( GemValue.createArray( values.get( methodName ), defaultValues.get( methodName ), TypeMirror.class ) );
            }
            else if ( "useEnums".equals( methodName ) ) {
                builder.setUseenums( GemValue.createArray( values.get( methodName ), defaultValues.get( methodName ), TypeMirror.class ) );
            }
            else if ( "imports".equals( methodName ) ) {
                builder.setImports( GemValue.createArray( values.get( methodName ), defaultValues.get( methodName ), TypeMirror.class ) );
            }
            else if ( "convertGenerate".equals( methodName ) ) {
                builder.setConvertgenerate( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), Boolean.class ) );
            }
            else if ( "mapperName".equals( methodName ) ) {
                builder.setMappername( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
            }
            else if ( "mapperNameSuffix".equals( methodName ) ) {
                builder.setMappernamesuffix( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), String.class ) );
            }
            else if ( "reverseConvertGenerate".equals( methodName ) ) {
                builder.setReverseconvertgenerate( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), Boolean.class ) );
            }
            else if ( "cycleAvoiding".equals( methodName ) ) {
                builder.setCycleavoiding( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), Boolean.class ) );
            }
            else if ( "unmappedSourcePolicy".equals( methodName ) ) {
                builder.setUnmappedsourcepolicy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
            }
            else if ( "unmappedTargetPolicy".equals( methodName ) ) {
                builder.setUnmappedtargetpolicy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
            }
            else if ( "typeConversionPolicy".equals( methodName ) ) {
                builder.setTypeconversionpolicy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
            }
            else if ( "collectionMappingStrategy".equals( methodName ) ) {
                builder.setCollectionmappingstrategy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
            }
            else if ( "nullValueMappingStrategy".equals( methodName ) ) {
                builder.setNullvaluemappingstrategy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
            }
            else if ( "nullValueIterableMappingStrategy".equals( methodName ) ) {
                builder.setNullvalueiterablemappingstrategy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
            }
            else if ( "nullValuePropertyMappingStrategy".equals( methodName ) ) {
                builder.setNullvaluepropertymappingstrategy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
            }
            else if ( "nullValueCheckStrategy".equals( methodName ) ) {
                builder.setNullvaluecheckstrategy( GemValue.createEnum( values.get( methodName ), defaultValues.get( methodName ) ) );
            }
            else if ( "mappingControl".equals( methodName ) ) {
                builder.setMappingcontrol( GemValue.create( values.get( methodName ), defaultValues.get( methodName ), TypeMirror.class ) );
            }
        }
        builder.setMirror( mirror );
        return builder.build();
    }

    /**
     * A builder that can be implemented by the user to define custom logic e.g. in the
     * build method, prior to creating the annotation gem.
     */
    public interface Builder {

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#target}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setTarget(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#uses}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setUses(GemValue> methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#useEnums}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setUseenums(GemValue> methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#imports}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setImports(GemValue> methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#convertGenerate}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setConvertgenerate(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#mapperName}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setMappername(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#mapperNameSuffix}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setMappernamesuffix(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#reverseConvertGenerate}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setReverseconvertgenerate(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#cycleAvoiding}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setCycleavoiding(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#unmappedSourcePolicy}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setUnmappedsourcepolicy(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#unmappedTargetPolicy}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setUnmappedtargetpolicy(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#typeConversionPolicy}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setTypeconversionpolicy(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#collectionMappingStrategy}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setCollectionmappingstrategy(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#nullValueMappingStrategy}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setNullvaluemappingstrategy(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#nullValueIterableMappingStrategy}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setNullvalueiterablemappingstrategy(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#nullValuePropertyMappingStrategy}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setNullvaluepropertymappingstrategy(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#nullValueCheckStrategy}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setNullvaluecheckstrategy(GemValue methodName );

       /**
        * Sets the {@link GemValue} for {@link AutoMapperGem#mappingControl}
        *
        * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
        */
        Builder setMappingcontrol(GemValue methodName );

        /**
         * Sets the annotation mirror
         *
         * @param mirror the mirror which this gem represents
         *
         * @return the {@link Builder} for this gem, representing {@link AutoMapperGem}
         */
          Builder setMirror( AnnotationMirror mirror );

        /**
         * The build method can be overriden in a custom custom implementation, which allows
         * the user to define his own custom validation on the annotation.
         *
         * @return the representation of the annotation
         */
        T build();
    }

    private static class BuilderImpl implements Builder {

        private GemValue target;
        private GemValue> uses;
        private GemValue> useEnums;
        private GemValue> imports;
        private GemValue convertGenerate;
        private GemValue mapperName;
        private GemValue mapperNameSuffix;
        private GemValue reverseConvertGenerate;
        private GemValue cycleAvoiding;
        private GemValue unmappedSourcePolicy;
        private GemValue unmappedTargetPolicy;
        private GemValue typeConversionPolicy;
        private GemValue collectionMappingStrategy;
        private GemValue nullValueMappingStrategy;
        private GemValue nullValueIterableMappingStrategy;
        private GemValue nullValuePropertyMappingStrategy;
        private GemValue nullValueCheckStrategy;
        private GemValue mappingControl;
        private AnnotationMirror mirror;

        public Builder setTarget(GemValue target ) {
            this.target = target;
            return this;
        }

        public Builder setUses(GemValue> uses ) {
            this.uses = uses;
            return this;
        }

        public Builder setUseenums(GemValue> useEnums ) {
            this.useEnums = useEnums;
            return this;
        }

        public Builder setImports(GemValue> imports ) {
            this.imports = imports;
            return this;
        }

        public Builder setConvertgenerate(GemValue convertGenerate ) {
            this.convertGenerate = convertGenerate;
            return this;
        }

        public Builder setMappername(GemValue mapperName ) {
            this.mapperName = mapperName;
            return this;
        }

        public Builder setMappernamesuffix(GemValue mapperNameSuffix ) {
            this.mapperNameSuffix = mapperNameSuffix;
            return this;
        }

        public Builder setReverseconvertgenerate(GemValue reverseConvertGenerate ) {
            this.reverseConvertGenerate = reverseConvertGenerate;
            return this;
        }

        public Builder setCycleavoiding(GemValue cycleAvoiding ) {
            this.cycleAvoiding = cycleAvoiding;
            return this;
        }

        public Builder setUnmappedsourcepolicy(GemValue unmappedSourcePolicy ) {
            this.unmappedSourcePolicy = unmappedSourcePolicy;
            return this;
        }

        public Builder setUnmappedtargetpolicy(GemValue unmappedTargetPolicy ) {
            this.unmappedTargetPolicy = unmappedTargetPolicy;
            return this;
        }

        public Builder setTypeconversionpolicy(GemValue typeConversionPolicy ) {
            this.typeConversionPolicy = typeConversionPolicy;
            return this;
        }

        public Builder setCollectionmappingstrategy(GemValue collectionMappingStrategy ) {
            this.collectionMappingStrategy = collectionMappingStrategy;
            return this;
        }

        public Builder setNullvaluemappingstrategy(GemValue nullValueMappingStrategy ) {
            this.nullValueMappingStrategy = nullValueMappingStrategy;
            return this;
        }

        public Builder setNullvalueiterablemappingstrategy(GemValue nullValueIterableMappingStrategy ) {
            this.nullValueIterableMappingStrategy = nullValueIterableMappingStrategy;
            return this;
        }

        public Builder setNullvaluepropertymappingstrategy(GemValue nullValuePropertyMappingStrategy ) {
            this.nullValuePropertyMappingStrategy = nullValuePropertyMappingStrategy;
            return this;
        }

        public Builder setNullvaluecheckstrategy(GemValue nullValueCheckStrategy ) {
            this.nullValueCheckStrategy = nullValueCheckStrategy;
            return this;
        }

        public Builder setMappingcontrol(GemValue mappingControl ) {
            this.mappingControl = mappingControl;
            return this;
        }

        public Builder  setMirror( AnnotationMirror mirror ) {
            this.mirror = mirror;
            return this;
        }

        public AutoMapperGem build() {
            return new AutoMapperGem( this );
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy