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