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 java.util.*; 022 023import org.apache.juneau.commons.reflect.*; 024import org.apache.juneau.marshall.encoders.*; 025import org.apache.juneau.marshall.httppart.*; 026import org.apache.juneau.marshall.serializer.*; 027import org.apache.juneau.rest.server.arg.*; 028import org.apache.juneau.rest.server.converter.*; 029import org.apache.juneau.rest.server.guard.*; 030import org.apache.juneau.rest.server.openapi.*; 031import org.apache.juneau.rest.server.processor.*; 032import org.apache.juneau.rest.server.staticfile.*; 033import org.apache.juneau.rest.server.swagger.*; 034 035/** 036 * Shared abstract base for the {@link RestBuilder} flavor builders ({@code RestServlet.Builder}, 037 * {@code RestResource.Builder}, {@code RestMixin.Builder}). 038 * 039 * <p> 040 * Each fluent {@code @Rest}-member setter is implemented <b>once</b> here and forwards into a backing 041 * {@code RestAnnotation.Builder} — the override bag. At {@link RestContext} construction time the bag is 042 * turned into a synthetic, highest-priority {@code @Rest} annotation that is prepended to the resource's 043 * {@code @Rest} chain, so builder-supplied values <b>take precedence</b> over the class's own 044 * {@link Rest @Rest} annotation values. 045 * 046 * <h5 class='section'>Self type (CRTP):</h5> 047 * 048 * <p> 049 * {@code SELF} is the concrete builder type, left open through the flavor builders and their user subclasses so 050 * that bespoke setters on a subclass chain with true covariant returns. Setters return {@link #self()}. 051 * 052 * @param <R> The resource type produced by {@link #build()}. 053 * @param <SELF> The concrete builder type (self type). 054 * @since 10.0.0 055 */ 056@SuppressWarnings({ 057 "java:S119", // 'SELF' (CRTP self-type) is intentional and clearer than a single-letter name. 058 "java:S1452", // Wildcard return on getResourceType() is intentional. 059 "unchecked" // CRTP self-type cast in self() is safe by construction. 060}) 061public abstract class AbstractRestBuilder<R,SELF extends AbstractRestBuilder<R,SELF>> implements RestBuilder<SELF> { 062 063 private final Class<R> resourceType; 064 private final RestAnnotation.Builder anno = RestAnnotation.create(); 065 private final Map<String,Object> extras = m(); 066 private Boolean mdcAsyncPropagation; 067 068 /** 069 * Constructor. 070 * 071 * @param resourceType The resource type produced by {@link #build()}. Must not be <jk>null</jk>. 072 */ 073 protected AbstractRestBuilder(Class<R> resourceType) { 074 this.resourceType = reqnn("resourceType", resourceType); 075 } 076 077 /** 078 * Returns this builder cast to the self type. 079 * 080 * @return This object. 081 */ 082 protected final SELF self() { 083 return (SELF)this; 084 } 085 086 /** 087 * Builds the configured resource instance. 088 * 089 * @return A new resource instance configured by this builder. 090 */ 091 public abstract R build(); 092 093 /** 094 * Reflectively instantiates the resource type, preferring a {@code (RestBuilder<?>)} constructor (constructor 095 * injection) and falling back to the no-arg constructor. 096 * 097 * <p> 098 * Flavor builder {@code build()} implementations call this then stash {@code this} on the returned instance. 099 * 100 * @return A new, uninitialized resource instance. 101 */ 102 protected R createResource() { 103 var ci = ClassInfo.of(resourceType); 104 var ctor = ci.getDeclaredConstructor(x -> x.hasParameterTypes(RestBuilder.class)).orElse(null); 105 if (ctor != null) 106 return ctor.accessible().newInstance(this); 107 var noArg = ci.getNoArgConstructor(Visibility.PRIVATE) 108 .orElseThrow(() -> isex("Resource class %s has no no-arg or RestBuilder<?> constructor.", resourceType.getName())); 109 return noArg.accessible().newInstance(); 110 } 111 112 //----------------------------------------------------------------------------------------------------------------- 113 // Override-bag accessors (consumed by RestContext during construction) 114 //----------------------------------------------------------------------------------------------------------------- 115 116 /** 117 * Returns the resource type produced by this builder. 118 * 119 * @return The resource type. Never <jk>null</jk>. 120 */ 121 public Class<?> getResourceType() { 122 return resourceType; 123 } 124 125 /** 126 * Returns the synthetic {@code @Rest} annotation carrying all builder-set members, for use as the 127 * highest-priority contributor of the {@code @Rest} resolution chain. 128 * 129 * @return The synthetic annotation. Never <jk>null</jk>. 130 */ 131 public Rest toRestAnnotation() { 132 return anno.build(); 133 } 134 135 /** 136 * Returns the programmatic MDC async-propagation override, or <jk>null</jk> if not set. 137 * 138 * @return The override, or <jk>null</jk> if not set. 139 */ 140 public Boolean getMdcAsyncPropagation() { 141 return mdcAsyncPropagation; 142 } 143 144 /** 145 * Returns the forward-compat extras set via {@link #set(String, Object)}. 146 * 147 * @return An unmodifiable view of the extras map. Never <jk>null</jk>. 148 */ 149 public Map<String,Object> getExtras() { 150 return u(extras); 151 } 152 153 //----------------------------------------------------------------------------------------------------------------- 154 // Identity & mounting 155 //----------------------------------------------------------------------------------------------------------------- 156 157 @Override /* RestBuilder<?> */ 158 public SELF path(String value) { anno.path(value); return self(); } 159 160 @Override /* RestBuilder<?> */ 161 public SELF paths(String... value) { anno.paths(value); return self(); } 162 163 @Override /* RestBuilder<?> */ 164 public SELF children(Class<?>... value) { anno.children(value); return self(); } 165 166 @Override /* RestBuilder<?> */ 167 public SELF mixins(Class<?>... value) { anno.mixins(value); return self(); } 168 169 @Override /* RestBuilder<?> */ 170 public SELF mixinDefs(Mixin... value) { anno.mixinDefs(value); return self(); } 171 172 @Override /* RestBuilder<?> */ 173 public SELF uriAuthority(String value) { anno.uriAuthority(value); return self(); } 174 175 @Override /* RestBuilder<?> */ 176 public SELF uriContext(String value) { anno.uriContext(value); return self(); } 177 178 @Override /* RestBuilder<?> */ 179 public SELF uriRelativity(String value) { anno.uriRelativity(value); return self(); } 180 181 @Override /* RestBuilder<?> */ 182 public SELF uriResolution(String value) { anno.uriResolution(value); return self(); } 183 184 //----------------------------------------------------------------------------------------------------------------- 185 // Marshalling 186 //----------------------------------------------------------------------------------------------------------------- 187 188 @Override /* RestBuilder<?> */ 189 public SELF serializers(Class<? extends Serializer>... value) { anno.serializers(value); return self(); } 190 191 @Override /* RestBuilder<?> */ 192 public SELF parsers(Class<?>... value) { anno.parsers(value); return self(); } 193 194 @Override /* RestBuilder<?> */ 195 public SELF encoders(Class<? extends Encoder>... value) { anno.encoders(value); return self(); } 196 197 @Override /* RestBuilder<?> */ 198 public SELF partSerializer(Class<? extends HttpPartSerializer> value) { anno.partSerializer(value); return self(); } 199 200 @Override /* RestBuilder<?> */ 201 public SELF partParser(Class<? extends HttpPartParser> value) { anno.partParser(value); return self(); } 202 203 @Override /* RestBuilder<?> */ 204 public SELF consumes(String... value) { anno.consumes(value); return self(); } 205 206 @Override /* RestBuilder<?> */ 207 public SELF produces(String... value) { anno.produces(value); return self(); } 208 209 @Override /* RestBuilder<?> */ 210 public SELF responseProcessors(Class<? extends ResponseProcessor>... value) { anno.responseProcessors(value); return self(); } 211 212 @Override /* RestBuilder<?> */ 213 public SELF allowedSerializerOptions(String... value) { anno.allowedSerializerOptions(value); return self(); } 214 215 @Override /* RestBuilder<?> */ 216 public SELF allowedParserOptions(String... value) { anno.allowedParserOptions(value); return self(); } 217 218 //----------------------------------------------------------------------------------------------------------------- 219 // Request behavior 220 //----------------------------------------------------------------------------------------------------------------- 221 222 @Override /* RestBuilder<?> */ 223 public SELF allowedHeaderParams(String value) { anno.allowedHeaderParams(value); return self(); } 224 225 @Override /* RestBuilder<?> */ 226 public SELF allowedMethodHeaders(String value) { anno.allowedMethodHeaders(value); return self(); } 227 228 @Override /* RestBuilder<?> */ 229 public SELF allowedMethodParams(String value) { anno.allowedMethodParams(value); return self(); } 230 231 @Override /* RestBuilder<?> */ 232 public SELF clientVersionHeader(String value) { anno.clientVersionHeader(value); return self(); } 233 234 @Override /* RestBuilder<?> */ 235 public SELF defaultAccept(String value) { anno.defaultAccept(value); return self(); } 236 237 @Override /* RestBuilder<?> */ 238 public SELF defaultContentType(String value) { anno.defaultContentType(value); return self(); } 239 240 @Override /* RestBuilder<?> */ 241 public SELF defaultCharset(String value) { anno.defaultCharset(value); return self(); } 242 243 @Override /* RestBuilder<?> */ 244 public SELF defaultRequestAttributes(String... value) { anno.defaultRequestAttributes(value); return self(); } 245 246 @Override /* RestBuilder<?> */ 247 public SELF defaultRequestHeaders(String... value) { anno.defaultRequestHeaders(value); return self(); } 248 249 @Override /* RestBuilder<?> */ 250 public SELF defaultResponseHeaders(String... value) { anno.defaultResponseHeaders(value); return self(); } 251 252 @Override /* RestBuilder<?> */ 253 public SELF disableContentParam(String value) { anno.disableContentParam(value); return self(); } 254 255 @Override /* RestBuilder<?> */ 256 public SELF maxInput(String value) { anno.maxInput(value); return self(); } 257 258 @Override /* RestBuilder<?> */ 259 public SELF restOpArgs(Class<? extends RestOpArg>... value) { anno.restOpArgs(value); return self(); } 260 261 //----------------------------------------------------------------------------------------------------------------- 262 // Security 263 //----------------------------------------------------------------------------------------------------------------- 264 265 @Override /* RestBuilder<?> */ 266 public SELF guards(Class<? extends RestGuard>... value) { anno.guards(value); return self(); } 267 268 @Override /* RestBuilder<?> */ 269 public SELF roleGuard(String value) { anno.roleGuard(value); return self(); } 270 271 @Override /* RestBuilder<?> */ 272 public SELF rolesDeclared(String value) { anno.rolesDeclared(value); return self(); } 273 274 @Override /* RestBuilder<?> */ 275 public SELF converters(Class<? extends RestConverter>... value) { anno.converters(value); return self(); } 276 277 //----------------------------------------------------------------------------------------------------------------- 278 // Lifecycle / perf 279 //----------------------------------------------------------------------------------------------------------------- 280 281 @Override /* RestBuilder<?> */ 282 public SELF eagerInit(String value) { anno.eagerInit(value); return self(); } 283 284 @Override /* RestBuilder<?> */ 285 public SELF lazyChildren(String value) { anno.lazyChildren(value); return self(); } 286 287 @Override /* RestBuilder<?> */ 288 public SELF virtualThreads(String value) { anno.virtualThreads(value); return self(); } 289 290 @Override /* RestBuilder<?> */ 291 public SELF asyncTimeoutMillis(String value) { anno.asyncTimeoutMillis(value); return self(); } 292 293 @Override /* RestBuilder<?> */ 294 public SELF asyncCompletionExecutor(String value) { anno.asyncCompletionExecutor(value); return self(); } 295 296 //----------------------------------------------------------------------------------------------------------------- 297 // Observability / logging / errors 298 //----------------------------------------------------------------------------------------------------------------- 299 300 @Override /* RestBuilder<?> */ 301 public SELF observability(String value) { anno.observability(value); return self(); } 302 303 @Override /* RestBuilder<?> */ 304 public SELF renderResponseStackTraces(String value) { anno.renderResponseStackTraces(value); return self(); } 305 306 @Override /* RestBuilder<?> */ 307 public SELF problemDetails(String value) { anno.problemDetails(value); return self(); } 308 309 @Override /* RestBuilder<?> */ 310 public SELF debugMarshalling(String value) { anno.debugMarshalling(value); return self(); } 311 312 //----------------------------------------------------------------------------------------------------------------- 313 // Docs / metadata / i18n / static files 314 //----------------------------------------------------------------------------------------------------------------- 315 316 @Override /* RestBuilder<?> */ 317 public SELF title(String... value) { anno.title(value); return self(); } 318 319 @Override /* RestBuilder<?> */ 320 public SELF description(String... value) { anno.description(value); return self(); } 321 322 @Override /* RestBuilder<?> */ 323 public SELF siteName(String value) { anno.siteName(value); return self(); } 324 325 @Override /* RestBuilder<?> */ 326 public SELF swaggerProvider(Class<? extends SwaggerProvider> value) { anno.swaggerProvider(value); return self(); } 327 328 @Override /* RestBuilder<?> */ 329 public SELF openApiProvider(Class<? extends OpenApiProvider> value) { anno.openApiProvider(value); return self(); } 330 331 @Override /* RestBuilder<?> */ 332 public SELF messages(String value) { anno.messages(value); return self(); } 333 334 @Override /* RestBuilder<?> */ 335 public SELF config(String value) { anno.config(value); return self(); } 336 337 @Override /* RestBuilder<?> */ 338 public SELF staticFiles(Class<? extends StaticFiles> value) { anno.staticFiles(value); return self(); } 339 340 @Override /* RestBuilder<?> */ 341 public SELF noInherit(String... value) { anno.noInherit(value); return self(); } 342 343 //----------------------------------------------------------------------------------------------------------------- 344 // Programmatic-only knob & escape hatch 345 //----------------------------------------------------------------------------------------------------------------- 346 347 @Override /* RestBuilder<?> */ 348 public SELF mdcAsyncPropagation(boolean value) { mdcAsyncPropagation = value; return self(); } 349 350 @Override /* RestBuilder<?> */ 351 public SELF set(String key, Object value) { extras.put(reqnn("key", key), value); return self(); } 352}