001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.rest.server; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020 021import org.apache.juneau.commons.*; 022import org.apache.juneau.marshall.encoders.*; 023import org.apache.juneau.marshall.httppart.*; 024import org.apache.juneau.marshall.serializer.*; 025import org.apache.juneau.rest.server.arg.*; 026import org.apache.juneau.rest.server.converter.*; 027import org.apache.juneau.rest.server.guard.*; 028import org.apache.juneau.rest.server.processor.*; 029 030/** 031 * Utility classes and methods for the {@link Mixin @Mixin} annotation. 032 * 033 * <h5 class='section'>See Also:</h5><ul> 034 * <li class='ja'>{@link Mixin} 035 * <li class='ja'>{@link Rest#mixinDefs()} 036 * </ul> 037 * 038 * @since 10.0.0 039 */ 040public class MixinAnnotation { 041 042 /** 043 * Prevents instantiation. 044 */ 045 private MixinAnnotation() {} 046 047 /** 048 * Builder class. 049 */ 050 @SuppressWarnings({ 051 "unchecked" // Type erasure requires cast for generic class-array fields. 052 }) 053 public static class Builder extends AnnotationObject.Builder { 054 055 Class<?> type = Object.class; 056 boolean mergeIntoHost = false; 057 Class<? extends RestGuard>[] guards = new Class[0]; 058 String roleGuard = ""; 059 String rolesDeclared = ""; 060 Class<? extends RestConverter>[] converters = new Class[0]; 061 Class<? extends Encoder>[] encoders = new Class[0]; 062 Class<? extends Serializer>[] serializers = new Class[0]; 063 Class<?>[] parsers = {}; 064 Class<? extends ResponseProcessor>[] responseProcessors = new Class[0]; 065 Class<? extends RestOpArg>[] restOpArgs = new Class[0]; 066 Class<? extends HttpPartSerializer> partSerializer = HttpPartSerializer.Void.class; 067 Class<? extends HttpPartParser> partParser = HttpPartParser.Void.class; 068 String messages = ""; 069 String[] defaultRequestHeaders = {}; 070 String[] defaultResponseHeaders = {}; 071 String[] defaultRequestAttributes = {}; 072 String[] produces = {}; 073 String[] consumes = {}; 074 String defaultAccept = ""; 075 String defaultContentType = ""; 076 String defaultCharset = ""; 077 String maxInput = ""; 078 String path = ""; 079 String[] paths = {}; 080 String[] noInherit = {}; 081 082 /** 083 * Constructor. 084 */ 085 protected Builder() { 086 super(Mixin.class); 087 } 088 089 /** 090 * Sets the {@link Mixin#type()} property on this annotation. 091 * 092 * @param value The new value for this property. 093 * @return This object. 094 */ 095 public Builder type(Class<?> value) { type = value; return this; } 096 097 /** 098 * Sets the {@link Mixin#mergeIntoHost()} property on this annotation. 099 * 100 * @param value The new value for this property. 101 * @return This object. 102 */ 103 public Builder mergeIntoHost(boolean value) { mergeIntoHost = value; return this; } 104 105 /** 106 * Sets the {@link Mixin#guards()} property on this annotation. 107 * 108 * @param value The new value for this property. 109 * @return This object. 110 */ 111 public Builder guards(Class<? extends RestGuard>... value) { guards = value; return this; } 112 113 /** 114 * Sets the {@link Mixin#roleGuard()} property on this annotation. 115 * 116 * @param value The new value for this property. 117 * @return This object. 118 */ 119 public Builder roleGuard(String value) { roleGuard = value; return this; } 120 121 /** 122 * Sets the {@link Mixin#rolesDeclared()} property on this annotation. 123 * 124 * @param value The new value for this property. 125 * @return This object. 126 */ 127 public Builder rolesDeclared(String value) { rolesDeclared = value; return this; } 128 129 /** 130 * Sets the {@link Mixin#converters()} property on this annotation. 131 * 132 * @param value The new value for this property. 133 * @return This object. 134 */ 135 public Builder converters(Class<? extends RestConverter>... value) { converters = value; return this; } 136 137 /** 138 * Sets the {@link Mixin#encoders()} property on this annotation. 139 * 140 * @param value The new value for this property. 141 * @return This object. 142 */ 143 public Builder encoders(Class<? extends Encoder>... value) { encoders = value; return this; } 144 145 /** 146 * Sets the {@link Mixin#serializers()} property on this annotation. 147 * 148 * @param value The new value for this property. 149 * @return This object. 150 */ 151 public Builder serializers(Class<? extends Serializer>... value) { serializers = value; return this; } 152 153 /** 154 * Sets the {@link Mixin#parsers()} property on this annotation. 155 * 156 * @param value The new value for this property. 157 * @return This object. 158 */ 159 public Builder parsers(Class<?>... value) { parsers = value; return this; } 160 161 /** 162 * Sets the {@link Mixin#responseProcessors()} property on this annotation. 163 * 164 * @param value The new value for this property. 165 * @return This object. 166 */ 167 public Builder responseProcessors(Class<? extends ResponseProcessor>... value) { responseProcessors = value; return this; } 168 169 /** 170 * Sets the {@link Mixin#restOpArgs()} property on this annotation. 171 * 172 * @param value The new value for this property. 173 * @return This object. 174 */ 175 public Builder restOpArgs(Class<? extends RestOpArg>... value) { restOpArgs = value; return this; } 176 177 /** 178 * Sets the {@link Mixin#partSerializer()} property on this annotation. 179 * 180 * @param value The new value for this property. 181 * @return This object. 182 */ 183 public Builder partSerializer(Class<? extends HttpPartSerializer> value) { partSerializer = value; return this; } 184 185 /** 186 * Sets the {@link Mixin#partParser()} property on this annotation. 187 * 188 * @param value The new value for this property. 189 * @return This object. 190 */ 191 public Builder partParser(Class<? extends HttpPartParser> value) { partParser = value; return this; } 192 193 /** 194 * Sets the {@link Mixin#messages()} property on this annotation. 195 * 196 * @param value The new value for this property. 197 * @return This object. 198 */ 199 public Builder messages(String value) { messages = value; return this; } 200 201 /** 202 * Sets the {@link Mixin#defaultRequestHeaders()} property on this annotation. 203 * 204 * @param value The new value for this property. 205 * @return This object. 206 */ 207 public Builder defaultRequestHeaders(String... value) { defaultRequestHeaders = value; return this; } 208 209 /** 210 * Sets the {@link Mixin#defaultResponseHeaders()} property on this annotation. 211 * 212 * @param value The new value for this property. 213 * @return This object. 214 */ 215 public Builder defaultResponseHeaders(String... value) { defaultResponseHeaders = value; return this; } 216 217 /** 218 * Sets the {@link Mixin#defaultRequestAttributes()} property on this annotation. 219 * 220 * @param value The new value for this property. 221 * @return This object. 222 */ 223 public Builder defaultRequestAttributes(String... value) { defaultRequestAttributes = value; return this; } 224 225 /** 226 * Sets the {@link Mixin#produces()} property on this annotation. 227 * 228 * @param value The new value for this property. 229 * @return This object. 230 */ 231 public Builder produces(String... value) { produces = value; return this; } 232 233 /** 234 * Sets the {@link Mixin#consumes()} property on this annotation. 235 * 236 * @param value The new value for this property. 237 * @return This object. 238 */ 239 public Builder consumes(String... value) { consumes = value; return this; } 240 241 /** 242 * Sets the {@link Mixin#defaultAccept()} property on this annotation. 243 * 244 * @param value The new value for this property. 245 * @return This object. 246 */ 247 public Builder defaultAccept(String value) { defaultAccept = value; return this; } 248 249 /** 250 * Sets the {@link Mixin#defaultContentType()} property on this annotation. 251 * 252 * @param value The new value for this property. 253 * @return This object. 254 */ 255 public Builder defaultContentType(String value) { defaultContentType = value; return this; } 256 257 /** 258 * Sets the {@link Mixin#defaultCharset()} property on this annotation. 259 * 260 * @param value The new value for this property. 261 * @return This object. 262 */ 263 public Builder defaultCharset(String value) { defaultCharset = value; return this; } 264 265 /** 266 * Sets the {@link Mixin#maxInput()} property on this annotation. 267 * 268 * @param value The new value for this property. 269 * @return This object. 270 */ 271 public Builder maxInput(String value) { maxInput = value; return this; } 272 273 /** 274 * Sets the {@link Mixin#path()} property on this annotation. 275 * 276 * @param value The new value for this property. 277 * @return This object. 278 */ 279 public Builder path(String value) { path = value; return this; } 280 281 /** 282 * Sets the {@link Mixin#paths()} property on this annotation. 283 * 284 * @param value The new value for this property. 285 * @return This object. 286 */ 287 public Builder paths(String... value) { paths = value; return this; } 288 289 /** 290 * Sets the {@link Mixin#noInherit()} property on this annotation. 291 * 292 * @param value The new value for this property. 293 * @return This object. 294 */ 295 public Builder noInherit(String... value) { noInherit = value; return this; } 296 297 /** 298 * Instantiates a new {@link Mixin @Mixin} object initialized with this builder. 299 * 300 * @return A new {@link Mixin @Mixin} object. 301 */ 302 public Mixin build() { 303 return new Impl(this); 304 } 305 } 306 307 @SuppressWarnings({ 308 "java:S2160" // equals() inherited from AnnotationObject compares all annotation interface methods; subclass fields are accessed via those methods. 309 }) 310 private static class Impl extends AnnotationObject implements Mixin { 311 312 private final Class<?> type; 313 private final boolean mergeIntoHost; 314 private final Class<? extends RestGuard>[] guards; 315 private final String roleGuard; 316 private final String rolesDeclared; 317 private final Class<? extends RestConverter>[] converters; 318 private final Class<? extends Encoder>[] encoders; 319 private final Class<? extends Serializer>[] serializers; 320 private final Class<?>[] parsers; 321 private final Class<? extends ResponseProcessor>[] responseProcessors; 322 private final Class<? extends RestOpArg>[] restOpArgs; 323 private final Class<? extends HttpPartSerializer> partSerializer; 324 private final Class<? extends HttpPartParser> partParser; 325 private final String messages; 326 private final String[] defaultRequestHeaders; 327 private final String[] defaultResponseHeaders; 328 private final String[] defaultRequestAttributes; 329 private final String[] produces; 330 private final String[] consumes; 331 private final String defaultAccept; 332 private final String defaultContentType; 333 private final String defaultCharset; 334 private final String maxInput; 335 private final String path; 336 private final String[] paths; 337 private final String[] noInherit; 338 339 Impl(MixinAnnotation.Builder b) { 340 super(b); 341 type = b.type; 342 mergeIntoHost = b.mergeIntoHost; 343 guards = cp(b.guards); 344 roleGuard = b.roleGuard; 345 rolesDeclared = b.rolesDeclared; 346 converters = cp(b.converters); 347 encoders = cp(b.encoders); 348 serializers = cp(b.serializers); 349 parsers = cp(b.parsers); 350 responseProcessors = cp(b.responseProcessors); 351 restOpArgs = cp(b.restOpArgs); 352 partSerializer = b.partSerializer; 353 partParser = b.partParser; 354 messages = b.messages; 355 defaultRequestHeaders = cp(b.defaultRequestHeaders); 356 defaultResponseHeaders = cp(b.defaultResponseHeaders); 357 defaultRequestAttributes = cp(b.defaultRequestAttributes); 358 produces = cp(b.produces); 359 consumes = cp(b.consumes); 360 defaultAccept = b.defaultAccept; 361 defaultContentType = b.defaultContentType; 362 defaultCharset = b.defaultCharset; 363 maxInput = b.maxInput; 364 path = b.path; 365 paths = cp(b.paths); 366 noInherit = cp(b.noInherit); 367 } 368 369 @Override /* Overridden from Mixin */ public Class<?> type() { return type; } 370 @Override /* Overridden from Mixin */ public boolean mergeIntoHost() { return mergeIntoHost; } 371 @Override /* Overridden from Mixin */ public Class<? extends RestGuard>[] guards() { return cp(guards); } 372 @Override /* Overridden from Mixin */ public String roleGuard() { return roleGuard; } 373 @Override /* Overridden from Mixin */ public String rolesDeclared() { return rolesDeclared; } 374 @Override /* Overridden from Mixin */ public Class<? extends RestConverter>[] converters() { return cp(converters); } 375 @Override /* Overridden from Mixin */ public Class<? extends Encoder>[] encoders() { return cp(encoders); } 376 @Override /* Overridden from Mixin */ public Class<? extends Serializer>[] serializers() { return cp(serializers); } 377 @Override /* Overridden from Mixin */ public Class<?>[] parsers() { return cp(parsers); } 378 @Override /* Overridden from Mixin */ public Class<? extends ResponseProcessor>[] responseProcessors() { return cp(responseProcessors); } 379 @Override /* Overridden from Mixin */ public Class<? extends RestOpArg>[] restOpArgs() { return cp(restOpArgs); } 380 @Override /* Overridden from Mixin */ public Class<? extends HttpPartSerializer> partSerializer() { return partSerializer; } 381 @Override /* Overridden from Mixin */ public Class<? extends HttpPartParser> partParser() { return partParser; } 382 @Override /* Overridden from Mixin */ public String messages() { return messages; } 383 @Override /* Overridden from Mixin */ public String[] defaultRequestHeaders() { return cp(defaultRequestHeaders); } 384 @Override /* Overridden from Mixin */ public String[] defaultResponseHeaders() { return cp(defaultResponseHeaders); } 385 @Override /* Overridden from Mixin */ public String[] defaultRequestAttributes() { return cp(defaultRequestAttributes); } 386 @Override /* Overridden from Mixin */ public String[] produces() { return cp(produces); } 387 @Override /* Overridden from Mixin */ public String[] consumes() { return cp(consumes); } 388 @Override /* Overridden from Mixin */ public String defaultAccept() { return defaultAccept; } 389 @Override /* Overridden from Mixin */ public String defaultContentType() { return defaultContentType; } 390 @Override /* Overridden from Mixin */ public String defaultCharset() { return defaultCharset; } 391 @Override /* Overridden from Mixin */ public String maxInput() { return maxInput; } 392 @Override /* Overridden from Mixin */ public String path() { return path; } 393 @Override /* Overridden from Mixin */ public String[] paths() { return cp(paths); } 394 @Override /* Overridden from Mixin */ public String[] noInherit() { return cp(noInherit); } 395 } 396 397 /** 398 * Builder creator. 399 * 400 * @return A new builder. 401 */ 402 public static Builder create() { 403 return new Builder(); 404 } 405 406 /** Default {@link Mixin} instance (empty overrides; {@code type=Object.class}). */ 407 public static final Mixin DEFAULT = create().build(); 408}