Annotation Type InjectAnnotation


  • @Documented
    @Target(ANNOTATION_TYPE)
    @Repeatable(InjectManyAnnotations.class)
    public @interface InjectAnnotation
    Meta-annotation that if detected on the annotation, will turn target annotation into special instruction to inject derived annotation code into target places. This annotated annotations - directives are called injection annotations, the derived annotation's code to be inserted is called target annotation. The injection annotations themselves are to be placed on attributes, abstract value types or packages, impacting all covered types and attributes for injection of target annotations (see type(), code()) into specified placed (see InjectAnnotation.Where) of the generated classes.
    Examples
    1) Inject Deprecated into fields "a" and "b" of the generated class
     @InjectAnnotation(type = Deprecated.class, target = Where.FIELD)
     @interface InjectDeprecated {}
     
     @Value.Immutable
     @InjectDeprecated
     interface Val {
       int a();
     
       int b();
     }
     
    2) Inject @TargetAnn(message="I'm BUILDER", of="Val2") onto generated ImmutableVal2.Builder
     @interface TargetAnn {
       String message();
     
       String of();
     }
     
     @InjectAnnotation(type = TargetAnn.class, code = "(message=[[echo]], of=\"[[!name]]\")", target = Where.BUILDER_TYPE)
     @interface InjectBuilderTarget {
       String echo();
     }
     
     @Value.Immutable
     @InjectBuilderTarget(echo = "I'm BUILDER")
     interface Val2 {
       int a();
     }
     
    3) Inject Point(x = 2, y = 3) on field "a" and Point(x = 4, y = 5) on field "b"
     @interface Point {
       int x();
     
       int y();
     }
     
     @InjectAnnotation(code = "@Point([[*]])", target = Where.FIELD)
     // watch-out for the relative or qualified name when putting annotation name into code attribute
     // that would be inserted and resolved from a generated code. Putting FQCN is recommended.
     @interface PointInject {
       int x();
     
       int y();
     }
     
     @Value.Immutable
     interface Val2 {
       @PointInject(x = 2, y = 3)
       String a();
     
       @PointInject(x = 4, y = 5)
       String b();
     }
     
    • Required Element Summary

      Required Elements 
      Modifier and Type Required Element Description
      InjectAnnotation.Where[] target
      The places where to put generated annotation.
    • Optional Element Summary

      Optional Elements 
      Modifier and Type Optional Element Description
      java.lang.String code
      Used to specify whole source code for the annotation.
      java.lang.String deduplicationKey
      Unique key is used when there's a need to prevent putting multiple conflicting annotations on the element if it's covered by injection annotations.
      boolean ifPresent
      Enables special behavior when annotation is injected to target() only if type() is set and corresponding model element have the same annotation.
      java.lang.Class<? extends java.lang.annotation.Annotation> type
      Specify annotation type, this is an alternative to specifying code().
    • Element Detail

      • target

        InjectAnnotation.Where[] target
        The places where to put generated annotation. If annotation type have been specified by type() (and is not overridden by #code()), then there will be element target check, otherwise (if fully specified by code()) annotation will be always placed and it's better match to target element type.
      • code

        java.lang.String code
        Used to specify whole source code for the annotation. Can specify whole target annotation(s) code or just attributes in parentheses and the type attribute will be used for the annotation fully qualified name. Special symbols can be used to further refine code of the annotation:
        • [[*]] inserts all attributes of defining annotation (the one which is annotated with InjectAnnotation) into target annotation code. Obviously those should match: be source-compatible. These will fully format attribute and literals, including commas between, but excluding any surrounding parentheses, so they can be mixed to non-overlapping hardcoded attributes.
        • [[!name]] inserts the simple name of the target attribute (or type) into annotation code, insertions are literal, without any quotes etc.
        • [[*names]] inserts the simple names of all attributes defined by abstract value type as as comma separated array initializer of quoted string literals. {"a", "b", "c"}
        • [[attr_name]] inserts source formatted value of injection annotation into code, where attr_name is one of the name of injection annotation attributes.

        If code includes @ symbol at the beginning, type() would be ignored, if code does not includes annotation start symbol and type() specified, then annotation symbol and type name would be prepended to the code(), so code essentially can be used to override set of annotation attributes.

        Default:
        ""
      • type

        java.lang.Class<? extends java.lang.annotation.Annotation> type
        Specify annotation type, this is an alternative to specifying code(). All the attributes from the annotated annotation (the one which is annotated by InjectAnnotation) are placed on abstract value type or abstract attribute. Default value is InjectAnnotation.class which is just a placeholder for unspecified value.
        See Also:
        code()
        Default:
        org.immutables.annotate.InjectAnnotation.class
      • ifPresent

        boolean ifPresent
        Enables special behavior when annotation is injected to target() only if type() is set and corresponding model element have the same annotation. code() expansion will still work and can override annotation type (if starts with full annotation definition).
        Returns:
        true if annotation insertion is triggered by the presence of the same annotation on a model element.
        Default:
        false
      • deduplicationKey

        java.lang.String deduplicationKey
        Unique key is used when there's a need to prevent putting multiple conflicting annotations on the element if it's covered by injection annotations. Putting it straight: when traversing all injection annotations (or as meta-annotations) which covers the element in question, starting from most specific to least specific, if there already was annotation injected by some key, the following annotations by the same key will be discarded. if not specified explicitly (empty string in the annotation attribute) the key will be auto-inferred as type() if specified or from code template string
        Default:
        ""