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.http.annotation; 018 019import static java.lang.annotation.ElementType.*; 020import static java.lang.annotation.RetentionPolicy.*; 021import static org.apache.juneau.commons.utils.CollectionUtils.*; 022 023import java.lang.annotation.*; 024import java.lang.reflect.*; 025 026import org.apache.juneau.*; 027import org.apache.juneau.annotation.*; 028import org.apache.juneau.httppart.*; 029import org.apache.juneau.commons.annotation.*; 030import org.apache.juneau.commons.reflect.*; 031import org.apache.juneau.svl.*; 032 033/** 034 * Utility classes and methods for the {@link Response @Response} annotation. 035 * 036 */ 037public class ResponseAnnotation { 038 /** 039 * Applies targeted {@link Response} annotations to a {@link org.apache.juneau.BeanContext.Builder}. 040 */ 041 public static class Applier extends AnnotationApplier<Response,BeanContext.Builder> { 042 043 /** 044 * Constructor. 045 * 046 * @param vr The resolver for resolving values in annotations. 047 */ 048 public Applier(VarResolverSession vr) { 049 super(Response.class, BeanContext.Builder.class, vr); 050 } 051 052 @Override 053 public void apply(AnnotationInfo<Response> ai, BeanContext.Builder b) { 054 Response a = ai.inner(); 055 if (isEmptyArray(a.on()) && isEmptyArray(a.onClass())) 056 return; 057 b.annotations(a); 058 } 059 } 060 061 /** 062 * A collection of {@link Response @Response annotations}. 063 */ 064 @Documented 065 @Target({ METHOD, TYPE }) 066 @Retention(RUNTIME) 067 @Inherited 068 public static @interface Array { 069 070 /** 071 * The child annotations. 072 * 073 * @return The annotation value. 074 */ 075 Response[] value(); 076 } 077 078 /** 079 * Builder class. 080 * 081 * <h5 class='section'>See Also:</h5><ul> 082 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)} 083 * </ul> 084 */ 085 public static class Builder extends AppliedAnnotationObject.BuilderTM { 086 087 private String[] description = {}; 088 private Class<? extends HttpPartParser> parser = HttpPartParser.Void.class; 089 private Class<? extends HttpPartSerializer> serializer = HttpPartSerializer.Void.class; 090 private Header[] headers = {}; 091 private Schema schema = SchemaAnnotation.DEFAULT; 092 private String[] examples = {}; 093 094 /** 095 * Constructor. 096 */ 097 protected Builder() { 098 super(Response.class); 099 } 100 101 /** 102 * Instantiates a new {@link Response @Response} object initialized with this builder. 103 * 104 * @return A new {@link Response @Response} object. 105 */ 106 public Response build() { 107 return new Object(this); 108 } 109 110 /** 111 * Sets the description property on this annotation. 112 * 113 * @param value The new value for this property. 114 * @return This object. 115 */ 116 public Builder description(String...value) { 117 description = value; 118 return this; 119 } 120 121 /** 122 * Sets the {@link Response#examples} property on this annotation. 123 * 124 * @param value The new value for this property. 125 * @return This object. 126 */ 127 public Builder examples(String...value) { 128 examples = value; 129 return this; 130 } 131 132 /** 133 * Sets the {@link Response#headers} property on this annotation. 134 * 135 * @param value The new value for this property. 136 * @return This object. 137 */ 138 public Builder headers(Header...value) { 139 headers = value; 140 return this; 141 } 142 143 /** 144 * Sets the {@link Response#parser} property on this annotation. 145 * 146 * @param value The new value for this property. 147 * @return This object. 148 */ 149 public Builder parser(Class<? extends HttpPartParser> value) { 150 parser = value; 151 return this; 152 } 153 154 /** 155 * Sets the {@link Response#schema} property on this annotation. 156 * 157 * @param value The new value for this property. 158 * @return This object. 159 */ 160 public Builder schema(Schema value) { 161 schema = value; 162 return this; 163 } 164 165 /** 166 * Sets the {@link Response#serializer} property on this annotation. 167 * 168 * @param value The new value for this property. 169 * @return This object. 170 */ 171 public Builder serializer(Class<? extends HttpPartSerializer> value) { 172 serializer = value; 173 return this; 174 } 175 176 @Override /* Overridden from AppliedAnnotationObject.Builder */ 177 public Builder on(String...value) { 178 super.on(value); 179 return this; 180 } 181 182 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 183 public Builder on(Class<?>...value) { 184 super.on(value); 185 return this; 186 } 187 188 @Override /* Overridden from AppliedOnClassAnnotationObject.Builder */ 189 public Builder onClass(Class<?>...value) { 190 super.onClass(value); 191 return this; 192 } 193 194 @Override /* Overridden from AppliedAnnotationObject.BuilderM */ 195 public Builder on(Method...value) { 196 super.on(value); 197 return this; 198 } 199 200 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 201 public Builder on(ClassInfo...value) { 202 super.on(value); 203 return this; 204 } 205 206 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 207 public Builder onClass(ClassInfo...value) { 208 super.onClass(value); 209 return this; 210 } 211 212 @Override /* Overridden from AppliedAnnotationObject.BuilderTM */ 213 public Builder on(MethodInfo...value) { 214 super.on(value); 215 return this; 216 } 217 218 } 219 220 private static class Object extends AppliedOnClassAnnotationObject implements Response { 221 222 private final String[] description; 223 private final Class<? extends HttpPartParser> parser; 224 private final Class<? extends HttpPartSerializer> serializer; 225 private final Header[] headers; 226 private final Schema schema; 227 private final String[] examples; 228 229 Object(ResponseAnnotation.Builder b) { 230 super(b); 231 description = copyOf(b.description); 232 examples = copyOf(b.examples); 233 headers = copyOf(b.headers); 234 parser = b.parser; 235 schema = b.schema; 236 serializer = b.serializer; 237 } 238 239 @Override /* Overridden from Response */ 240 public String[] examples() { 241 return examples; 242 } 243 244 @Override /* Overridden from Response */ 245 public Header[] headers() { 246 return headers; 247 } 248 249 @Override /* Overridden from Response */ 250 public Class<? extends HttpPartParser> parser() { 251 return parser; 252 } 253 254 @Override /* Overridden from Response */ 255 public Schema schema() { 256 return schema; 257 } 258 259 @Override /* Overridden from Response */ 260 public Class<? extends HttpPartSerializer> serializer() { 261 return serializer; 262 } 263 264 @Override /* Overridden from annotation */ 265 public String[] description() { 266 return description; 267 } 268 } 269 270 /** Default value */ 271 public static final Response DEFAULT = create().build(); 272 273 /** 274 * Instantiates a new builder for this class. 275 * 276 * @return A new builder object. 277 */ 278 public static Builder create() { 279 return new Builder(); 280 } 281 282 /** 283 * Instantiates a new builder for this class. 284 * 285 * @param on The targets this annotation applies to. 286 * @return A new builder object. 287 */ 288 public static Builder create(Class<?>...on) { 289 return create().on(on); 290 } 291 292 /** 293 * Instantiates a new builder for this class. 294 * 295 * @param on The targets this annotation applies to. 296 * @return A new builder object. 297 */ 298 public static Builder create(String...on) { 299 return create().on(on); 300 } 301 302 /** 303 * Returns <jk>true</jk> if the specified annotation contains all default values. 304 * 305 * @param a The annotation to check. 306 * @return <jk>true</jk> if the specified annotation contains all default values. 307 */ 308 public static boolean empty(Response a) { 309 return a == null || DEFAULT.equals(a); 310 } 311}