001package io.avaje.jsonb;
002
003import java.lang.annotation.ElementType;
004import java.lang.annotation.Repeatable;
005import java.lang.annotation.Retention;
006import java.lang.annotation.Target;
007
008import static java.lang.annotation.RetentionPolicy.CLASS;
009
010/**
011 * Marks a type for JSON support.
012 */
013@Retention(CLASS)
014@Target(ElementType.TYPE)
015public @interface Json {
016
017  /**
018   * Specify the naming convention to use for the properties on this type.
019   */
020  Naming naming() default Naming.Match;
021
022  /**
023   * When {@code @Json.SubType} is used this specifies the name of the property
024   * field that holds the type name (discriminator value).
025   * <p>
026   * This defaults to {@code @type} when unspecified.
027   */
028  String typeProperty() default "";
029
030  /**
031   * Specify types to generate JsonAdapters for.
032   * <p>
033   * These types are typically in an external project / dependency or otherwise
034   * types that we can't or don't want to explicitly annotate with {@code @Json}.
035   */
036  @Retention(CLASS)
037  @Target({ElementType.TYPE, ElementType.PACKAGE})
038  @interface Import {
039
040    /**
041     * Specify types to generate Json Adapters for.
042     */
043    Class<?>[] value();
044  }
045
046  /**
047   * Override the json property name.
048   */
049  @Retention(CLASS)
050  @Target({ElementType.FIELD})
051  @interface Property {
052
053    /**
054     * Specify the name for this property.
055     */
056    String value();
057  }
058
059  /**
060   * Exclude the property from serialization, deserialization or both.
061   * <p>
062   * We can explicitly use {@code deserialize=true} to include the property in
063   * deserialization but not serialization. For example, we might do this on
064   * a property that represents a secret like a password.
065   * <p>
066   * We can explicitly use {@code serialize=true} to include the property in
067   * serialization but not deserialization.
068   */
069  @Retention(CLASS)
070  @Target({ElementType.FIELD})
071  @interface Ignore {
072
073    /**
074     * Set this explicitly to true to include in serialization.
075     */
076    boolean serialize() default false;
077
078    /**
079     * Set this explicitly to true to include in deserialization.
080     */
081    boolean deserialize() default false;
082  }
083
084  /**
085   * Annotate a {@code Map<String,Object>} field to hold unmapped json properties.
086   * <p>
087   * When reading unknown properties from json content these are read and put into
088   * this map. When writing json this map is included back into the content.
089   *
090   * <pre>{@code
091   *
092   *   @Json.Unmapped
093   *   Map<String, Object> unmapped;
094   *
095   * }</pre>
096   */
097  @Retention(CLASS)
098  @Target({ElementType.FIELD})
099  @interface Unmapped {
100
101  }
102
103  /**
104   * Specify the subtypes that a given type can be represented as.
105   * <p>
106   * This is used on an interface type, abstract type or type with inheritance
107   * to indicate all the concrete subtypes that can represent the type.
108   * <p>
109   * In the example below the abstract Vehicle type has 2 concrete subtypes
110   * of Car and Truck that can represent the type.
111   *
112   * <pre>{@code
113   *
114   *   @Json
115   *   @Json.SubType(type = Car.class)
116   *   @Json.SubType(type = Truck.class, name = "TRUCK")
117   *   public abstract class Vehicle {
118   *    ...
119   *
120   * }</pre>
121   */
122  @Retention(CLASS)
123  @Target({ElementType.TYPE})
124  @Repeatable(SubTypes.class)
125  @interface SubType {
126
127    /**
128     * The concrete type that extends or implements the base type.
129     */
130    Class<?> type();
131
132    /**
133     * The name or "discriminator value" that is used to identify the type.
134     * <p>
135     * When unspecified this is the short name of the class.
136     */
137    String name() default "";
138  }
139
140  /**
141   * Container of all the concrete SubType's that an interface type or abstract
142   * type can be represented as.
143   */
144  @Retention(CLASS)
145  @Target({ElementType.TYPE})
146  @interface SubTypes {
147
148    SubType[] value();
149  }
150
151
152  /**
153   * The naming convention that we can use for a given type.
154   */
155  enum Naming {
156    Match,
157    LowerHyphen,
158    LowerUnderscore,
159    LowerSpace,
160    UpperCamel,
161    UpperHyphen,
162    UpperUnderscore,
163    UpperSpace
164  }
165}