Class MappingProcessor

  • All Implemented Interfaces:
    javax.annotation.processing.Processor

    @SupportedAnnotationTypes("org.mapstruct.Mapper")
    @SupportedOptions({"mapstruct.suppressGeneratorTimestamp","mapstruct.suppressGeneratorVersionInfoComment","mapstruct.unmappedTargetPolicy","mapstruct.unmappedSourcePolicy","mapstruct.defaultComponentModel","mapstruct.defaultInjectionStrategy","mapstruct.disableBuilders","mapstruct.verbose"})
    public class MappingProcessor
    extends javax.annotation.processing.AbstractProcessor
    A JSR 269 annotation Processor which generates the implementations for mapper interfaces (interfaces annotated with @Mapper).

    Implementation notes:

    The generation happens by incrementally building up a model representation of each mapper to be generated (a Mapper object), which is then written into the resulting Java source file.

    The model instantiation and processing happens in several phases/passes by applying a sequence of ModelElementProcessors. The processors to apply are retrieved using the Java service loader mechanism and are processed in order of their priority. The general processing flow is this:

    • retrieve mapping methods
    • create the Mapper model
    • perform enrichments and modifications (e.g. add annotations for dependency injection)
    • if no error occurred, write out the model into Java source files

    For reading annotation attributes, gems as generated with help of Gem Tools. These gems allow comfortable access to annotations and their attributes without depending on their class objects.

    The creation of Java source files is done using the FreeMarker template engine. Each node of the mapper model has a corresponding FreeMarker template file which provides the Java representation of that element and can include sub-elements via a custom FreeMarker directive. That way writing out a root node of the model (Mapper) will recursively include all contained sub-elements (such as its methods, their property mappings etc.).

    • Field Detail

      • ANNOTATIONS_CLAIMED_EXCLUSIVELY

        private static final boolean ANNOTATIONS_CLAIMED_EXCLUSIVELY
        Whether this processor claims all processed annotations exclusively or not.
        See Also:
        Constant Field Values
      • SUPPRESS_GENERATOR_TIMESTAMP

        protected static final java.lang.String SUPPRESS_GENERATOR_TIMESTAMP
        See Also:
        Constant Field Values
      • SUPPRESS_GENERATOR_VERSION_INFO_COMMENT

        protected static final java.lang.String SUPPRESS_GENERATOR_VERSION_INFO_COMMENT
        See Also:
        Constant Field Values
      • UNMAPPED_TARGET_POLICY

        protected static final java.lang.String UNMAPPED_TARGET_POLICY
        See Also:
        Constant Field Values
      • UNMAPPED_SOURCE_POLICY

        protected static final java.lang.String UNMAPPED_SOURCE_POLICY
        See Also:
        Constant Field Values
      • DEFAULT_COMPONENT_MODEL

        protected static final java.lang.String DEFAULT_COMPONENT_MODEL
        See Also:
        Constant Field Values
      • DEFAULT_INJECTION_STRATEGY

        protected static final java.lang.String DEFAULT_INJECTION_STRATEGY
        See Also:
        Constant Field Values
      • ALWAYS_GENERATE_SERVICE_FILE

        protected static final java.lang.String ALWAYS_GENERATE_SERVICE_FILE
        See Also:
        Constant Field Values
      • DISABLE_BUILDERS

        protected static final java.lang.String DISABLE_BUILDERS
        See Also:
        Constant Field Values
      • deferredMappers

        private java.util.Set<MappingProcessor.DeferredMapper> deferredMappers
        Any mappers for which an implementation cannot be generated in the current round because they have source/target types with incomplete hierarchies (as super-types are to be generated by other processors). They will be processed in subsequent rounds.

        If the hierarchy of a mapper's source/target types is never completed (i.e. the missing super-types are not generated by other processors), this mapper will not be generated; That's fine, the compiler will raise an error due to the inconsistent Java types used as source or target anyways.

    • Constructor Detail

      • MappingProcessor

        public MappingProcessor()
    • Method Detail

      • init

        public void init​(javax.annotation.processing.ProcessingEnvironment processingEnv)
        Specified by:
        init in interface javax.annotation.processing.Processor
        Overrides:
        init in class javax.annotation.processing.AbstractProcessor
      • createOptions

        private Options createOptions()
      • getSupportedSourceVersion

        public javax.lang.model.SourceVersion getSupportedSourceVersion()
        Specified by:
        getSupportedSourceVersion in interface javax.annotation.processing.Processor
        Overrides:
        getSupportedSourceVersion in class javax.annotation.processing.AbstractProcessor
      • process

        public boolean process​(java.util.Set<? extends javax.lang.model.element.TypeElement> annotations,
                               javax.annotation.processing.RoundEnvironment roundEnvironment)
        Specified by:
        process in interface javax.annotation.processing.Processor
        Specified by:
        process in class javax.annotation.processing.AbstractProcessor
      • getAndResetDeferredMappers

        private java.util.Set<javax.lang.model.element.TypeElement> getAndResetDeferredMappers()
        Gets fresh copies of all mappers deferred from previous rounds (the originals may contain references to erroneous source/target type elements).
      • getMappers

        private java.util.Set<javax.lang.model.element.TypeElement> getMappers​(java.util.Set<? extends javax.lang.model.element.TypeElement> annotations,
                                                                               javax.annotation.processing.RoundEnvironment roundEnvironment)
      • processMapperElements

        private void processMapperElements​(java.util.Set<javax.lang.model.element.TypeElement> mapperElements,
                                           RoundContext roundContext)
      • getDeclaredTypesNotToBeImported

        private java.util.Map<java.lang.String,​java.lang.String> getDeclaredTypesNotToBeImported​(javax.lang.model.element.TypeElement element)
      • handleUncaughtError

        private void handleUncaughtError​(javax.lang.model.element.Element element,
                                         java.lang.Throwable thrown)
      • processMapperTypeElement

        private void processMapperTypeElement​(ModelElementProcessor.ProcessorContext context,
                                              javax.lang.model.element.TypeElement mapperTypeElement)
        Applies all registered ModelElementProcessors to the given mapper type.
        Parameters:
        context - The processor context.
        mapperTypeElement - The mapper type element.
      • getProcessors

        private java.lang.Iterable<ModelElementProcessor<?,​?>> getProcessors()
        Retrieves all model element processors, ordered by their priority value (with the method retrieval processor having the lowest priority value (1) and the code generation processor the highest priority value.
        Returns:
        A list with all model element processors.
      • asTypeElement

        private javax.lang.model.element.TypeElement asTypeElement​(javax.lang.model.element.Element element)