001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.rest;
014
015import static org.apache.juneau.BeanContext.*;
016import static org.apache.juneau.internal.ArrayUtils.*;
017import static org.apache.juneau.internal.ClassUtils.*;
018import static org.apache.juneau.internal.StringUtils.*;
019import static org.apache.juneau.parser.Parser.*;
020import static org.apache.juneau.rest.RestContext.*;
021import static org.apache.juneau.rest.util.RestUtils.*;
022import static org.apache.juneau.serializer.Serializer.*;
023
024import java.lang.reflect.Method;
025import java.nio.charset.*;
026import java.util.*;
027
028import javax.servlet.*;
029
030import org.apache.juneau.*;
031import org.apache.juneau.config.*;
032import org.apache.juneau.config.vars.*;
033import org.apache.juneau.encoders.*;
034import org.apache.juneau.http.*;
035import org.apache.juneau.httppart.*;
036import org.apache.juneau.internal.*;
037import org.apache.juneau.oapi.*;
038import org.apache.juneau.parser.*;
039import org.apache.juneau.rest.annotation.*;
040import org.apache.juneau.rest.reshandlers.*;
041import org.apache.juneau.rest.util.RestUtils;
042import org.apache.juneau.rest.vars.*;
043import org.apache.juneau.rest.widget.*;
044import org.apache.juneau.serializer.*;
045import org.apache.juneau.svl.*;
046import org.apache.juneau.svl.vars.*;
047import org.apache.juneau.utils.*;
048
049/**
050 * Defines the initial configuration of a <code>RestServlet</code> or <code>@RestResource</code> annotated object.
051 *
052 * <p>
053 * An extension of the {@link ServletConfig} object used during servlet initialization.
054 *
055 * <p>
056 * Provides access to the following initialized resources:
057 * <ul>
058 *    <li>{@link #getConfig()} - The external configuration for this resource.
059 *    <li>{@link #getProperties()} - The modifiable configuration properties for this resource.
060 *    <li>{@link #getVarResolverBuilder()} - The variable resolver for this resource.
061 * </ul>
062 *
063 * <p>
064 * Methods are provided for overriding or augmenting the information provided by the <ja>@RestResource</ja> annotation.
065 * In general, most information provided in the <ja>@RestResource</ja> annotation can be specified programmatically
066 * through calls on this object.
067 *
068 * <p>
069 * To interact with this object, simply pass it in as a constructor argument or in an INIT hook.
070 * <p class='bcode w800'>
071 *    <jc>// Option #1 - Pass in through constructor.</jc>
072 *    <jk>public</jk> MyResource(RestContextBuilder builder) {
073 *          builder
074 *             .pojoSwaps(CalendarSwap.<jsf>RFC2822DTZ</jsf>.<jk>class</jk>)
075 *             .set(<jsf>PARSER_debug</jsf>, <jk>true</jk>);
076 *    }
077 *
078 *    <jc>// Option #2 - Use an INIT hook.</jc>
079 *    <ja>@RestHook</ja>(<jsf>INIT</jsf>)
080 *    <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
081 *          builder
082 *             .pojoSwaps(CalendarSwap.<jsf>RFC2822DTZ</jsf>.<jk>class</jk>)
083 *             .set(<jsf>PARSER_debug</jsf>, <jk>true</jk>);
084 *    }
085 * </p>
086 *
087 * <h5 class='section'>See Also:</h5>
088 * <ul>
089 *    <li class='link'>{@doc juneau-rest-server.RestContext}
090 * </ul>
091 */
092public class RestContextBuilder extends BeanContextBuilder implements ServletConfig {
093
094   final ServletConfig inner;
095
096   Class<?> resourceClass;
097   Object resource;
098   ServletContext servletContext;
099   RestContext parentContext;
100
101   //-----------------------------------------------------------------------------------------------------------------
102   // The following fields are meant to be modifiable.
103   // They should not be declared final.
104   // Read-only snapshots of these will be made in RestServletContext.
105   //-----------------------------------------------------------------------------------------------------------------
106
107   RestContextProperties properties;
108   Config config;
109   VarResolverBuilder varResolverBuilder;
110   String path;
111   HtmlDocBuilder htmlDocBuilder;
112
113   RestContextBuilder(ServletConfig servletConfig, Class<?> resourceClass, RestContext parentContext) throws ServletException {
114      this.inner = servletConfig;
115      this.resourceClass = resourceClass;
116      this.parentContext = parentContext;
117
118      properties = new RestContextProperties();
119
120      // Default values.
121      logger(BasicRestLogger.class);
122      partSerializer(OpenApiSerializer.class);
123      partParser(OpenApiParser.class);
124      staticFileResponseHeader("Cache-Control", "max-age=86400, public");
125      encoders(IdentityEncoder.INSTANCE);
126
127      try {
128
129         htmlDocBuilder = new HtmlDocBuilder(properties);
130         varResolverBuilder = new VarResolverBuilder()
131            .defaultVars()
132            .vars(ConfigVar.class)
133            .vars(FileVar.class)
134            .contextObject("crm", new ClasspathResourceManager(resourceClass));
135
136         VarResolver vr = varResolverBuilder.build();
137
138         Map<Class<?>,RestResource> restResourceAnnotationsParentFirst = getAnnotationsMapParentFirst(RestResource.class, resourceClass);
139
140         // Find our config file.  It's the last non-empty @RestResource(config).
141         String configPath = "";
142         for (RestResource r : restResourceAnnotationsParentFirst.values())
143            if (! r.config().isEmpty())
144               configPath = r.config();
145         String cf = vr.resolve(configPath);
146         ConfigBuilder cb = Config.create().varResolver(vr);
147         if (! cf.isEmpty())
148            cb.name(cf);
149
150         this.config = cb.build();
151
152         // Add our config file to the variable resolver.
153         varResolverBuilder.contextObject(ConfigVar.SESSION_config, config);
154         vr = varResolverBuilder.build();
155
156         // Add the servlet init parameters to our properties.
157         if (servletConfig != null) {
158            for (Enumeration<String> ep = servletConfig.getInitParameterNames(); ep.hasMoreElements();) {
159               String p = ep.nextElement();
160               String initParam = servletConfig.getInitParameter(p);
161               set(vr.resolve(p), vr.resolve(initParam));
162            }
163         }
164
165         // Load stuff from parent-to-child order.
166         // This allows child settings to overwrite parent settings.
167         for (Map.Entry<Class<?>,RestResource> e : restResourceAnnotationsParentFirst.entrySet()) {
168            Class<?> c = e.getKey();
169            RestResource r = e.getValue();
170            for (Property p : r.properties())
171               set(vr.resolve(p.name()), vr.resolve(p.value()));
172            for (String p : r.flags())
173               set(p, true);
174            serializers(false, merge(ObjectUtils.toType(psb.peek(REST_serializers), Object[].class), r.serializers()));
175            parsers(false, merge(ObjectUtils.toType(psb.peek(REST_parsers), Object[].class), r.parsers()));
176            partSerializer(r.partSerializer());
177            partParser(r.partParser());
178            encoders(r.encoders());
179            if (r.produces().length > 0)
180               produces(false, resolveVars(vr, r.produces()));
181            if (r.consumes().length > 0)
182               consumes(false, resolveVars(vr, r.consumes()));
183            defaultRequestHeaders(resolveVars(vr, r.defaultRequestHeaders()));
184            defaultAccept(vr.resolve(r.defaultAccept()));
185            defaultContentType(vr.resolve(r.defaultContentType()));
186            defaultResponseHeaders(resolveVars(vr, r.defaultResponseHeaders()));
187            responseHandlers(r.responseHandlers());
188            converters(r.converters());
189            guards(reverse(r.guards()));
190            children(r.children());
191            beanFilters(false, merge(ObjectUtils.toType(psb.peek(BEAN_beanFilters), Object[].class), r.beanFilters()));
192            pojoSwaps(false, merge(ObjectUtils.toType(psb.peek(BEAN_pojoSwaps), Object[].class), r.pojoSwaps()));
193            paramResolvers(r.paramResolvers());
194            serializerListener(r.serializerListener());
195            parserListener(r.parserListener());
196            uriContext(vr.resolve(r.uriContext()));
197            uriAuthority(vr.resolve(r.uriAuthority()));
198            uriRelativity(vr.resolve(r.uriRelativity()));
199            uriResolution(vr.resolve(r.uriResolution()));
200            for (String mapping : r.staticFiles())
201               staticFiles(c, vr.resolve(mapping));
202            if (! r.messages().isEmpty())
203               messages(c, vr.resolve(r.messages()));
204            staticFileResponseHeaders(resolveVars(vr, r.staticFileResponseHeaders()));
205            if (! r.useClasspathResourceCaching().isEmpty())
206               useClasspathResourceCaching(Boolean.valueOf(vr.resolve(r.useClasspathResourceCaching())));
207            if (r.classpathResourceFinder() != ClasspathResourceFinder.Null.class)
208               classpathResourceFinder(r.classpathResourceFinder());
209            if (! r.path().isEmpty())
210               path(vr.resolve(r.path()));
211            if (! r.clientVersionHeader().isEmpty())
212               clientVersionHeader(vr.resolve(r.clientVersionHeader()));
213            if (r.resourceResolver() != RestResourceResolver.Null.class)
214               resourceResolver(r.resourceResolver());
215            if (r.logger() != RestLogger.Null.class)
216               logger(r.logger());
217            if (r.callHandler() != RestCallHandler.Null.class)
218               callHandler(r.callHandler());
219            if (r.infoProvider() != RestInfoProvider.Null.class)
220               infoProvider(r.infoProvider());
221            if (! r.allowHeaderParams().isEmpty())
222               allowHeaderParams(Boolean.valueOf(vr.resolve(r.allowHeaderParams())));
223            if (! r.allowedMethodParams().isEmpty())
224               allowedMethodParams(vr.resolve(r.allowedMethodParams()));
225            if (! r.allowBodyParam().isEmpty())
226               allowBodyParam(Boolean.valueOf(vr.resolve(r.allowBodyParam())));
227            if (! r.renderResponseStackTraces().isEmpty())
228               renderResponseStackTraces(Boolean.valueOf(vr.resolve(r.renderResponseStackTraces())));
229            if (! r.useStackTraceHashes().isEmpty())
230               useStackTraceHashes(Boolean.valueOf(vr.resolve(r.useStackTraceHashes())));
231            if (! r.defaultCharset().isEmpty())
232               defaultCharset(vr.resolve(r.defaultCharset()));
233            if (! r.maxInput().isEmpty())
234               maxInput(vr.resolve(r.maxInput()));
235            if (! r.debug().isEmpty())
236               debug(Boolean.valueOf(vr.resolve(r.debug())));
237            mimeTypes(resolveVars(vr, r.mimeTypes()));
238
239            HtmlDoc hd = r.htmldoc();
240            widgets(hd.widgets());
241            htmlDocBuilder.process(hd);
242         }
243
244         responseHandlers(
245            ReaderHandler.class,
246            InputStreamHandler.class,
247            DefaultHandler.class
248         );
249
250      } catch (Exception e) {
251         throw new ServletException(e);
252      }
253   }
254
255   @Override /* BeanContextBuilder */
256   public RestContext build() {
257      try {
258         return new RestContext(this);
259      } catch (RestException e) {
260         throw e;
261      } catch (Exception e) {
262         throw new RuntimeException(e);
263      }
264   }
265
266   private static String[] resolveVars(VarResolver vr, String[] in) {
267      String[] out = new String[in.length];
268      for (int i = 0; i < in.length; i++)
269         out[i] = vr.resolve(in[i]);
270      return out;
271   }
272
273   /*
274    * Calls all @RestHook(INIT) methods on the specified resource object.
275    */
276   RestContextBuilder init(Object resource) throws ServletException {
277      this.resource = resource;
278
279      // Once we have the resource object, we can construct the Widgets.
280      // We want to do that here so that we can update the script/style properties while they're still modifiable.
281      HtmlDocBuilder hdb = getHtmlDocBuilder();
282      PropertyStore ps = getPropertyStore();
283      Widget[] widgets = ps.getInstanceArrayProperty(REST_widgets, Widget.class, new Widget[0], true, ps, resource);
284      for (Widget w : widgets) {
285         hdb.script("INHERIT", "$W{"+w.getName()+".script}");
286         hdb.style("INHERIT", "$W{"+w.getName()+".style}");
287      }
288      widgets(false, widgets);
289
290      Map<String,Method> map = new LinkedHashMap<>();
291      for (Method m : ClassUtils.getAllMethods(this.resourceClass, true)) {
292         if (m.isAnnotationPresent(RestHook.class) && m.getAnnotation(RestHook.class).value() == HookEvent.INIT) {
293            setAccessible(m, false);
294            String sig = ClassUtils.getMethodSignature(m);
295            if (! map.containsKey(sig))
296               map.put(sig, m);
297         }
298      }
299      for (Method m : map.values()) {
300         ClassUtils.assertArgsOfType(m, RestContextBuilder.class, ServletConfig.class);
301         Class<?>[] pt = m.getParameterTypes();
302         Object[] args = new Object[pt.length];
303         for (int i = 0; i < args.length; i++) {
304            if (pt[i] == RestContextBuilder.class)
305               args[i] = this;
306            else
307               args[i] = this.inner;
308         }
309         try {
310            m.invoke(resource, args);
311         } catch (Exception e) {
312            throw new RestServletException("Exception thrown from @RestHook(INIT) method {0}.", m).initCause(e);
313         }
314      }
315      return this;
316   }
317
318   RestContextBuilder servletContext(ServletContext servletContext) {
319      this.servletContext = servletContext;
320      return this;
321   }
322
323   /**
324    * Adds the specified {@link Var} classes to this config.
325    *
326    * <p>
327    * These variables affect the variable resolver returned by {@link RestRequest#getVarResolverSession()} which is
328    * used to resolve string variables of the form <js>"$X{...}"</js>.
329    *
330    * <p>
331    * See {@link RestContext#getVarResolver()} for a list of predefined variables.
332    *
333    * @param vars The {@link Var} classes to add to this config.
334    * @return This object (for method chaining).
335    */
336   public RestContextBuilder vars(Class<?>...vars) {
337      this.varResolverBuilder.vars(vars);
338      return this;
339   }
340
341   /**
342    * Adds a var context object to this config.
343    *
344    * <p>
345    * Var context objects are read-only objects associated with the variable resolver for vars that require external
346    * information.
347    *
348    * <p>
349    * For example, the {@link ConfigVar} needs access to this resource's {@link Config} through the
350    * {@link ConfigVar#SESSION_config} object that can be specified as either a session object (temporary) or
351    * context object (permanent).
352    * In this case, we call the following code to add it to the context map:
353    * <p class='bcode w800'>
354    *    config.addVarContextObject(<jsf>SESSION_config</jsf>, configFile);
355    * </p>
356    *
357    * @param name The context object key (i.e. the name that the Var class looks for).
358    * @param object The context object.
359    * @return This object (for method chaining).
360    */
361   public RestContextBuilder varContextObject(String name, Object object) {
362      this.varResolverBuilder.contextObject(name, object);
363      return this;
364   }
365
366   /**
367    * Overwrites the default config file with a custom config file.
368    *
369    * <p>
370    * By default, the config file is determined using the {@link RestResource#config() @RestResource(config)}
371    * annotation.
372    * This method allows you to programmatically override it with your own custom config file.
373    *
374    * @param config The new config file.
375    * @return This object (for method chaining).
376    */
377   public RestContextBuilder config(Config config) {
378      this.config = config;
379      return this;
380   }
381
382   /**
383    * Returns an instance of an HTMLDOC builder for setting HTMLDOC-related properties.
384    *
385    * @return An instance of an HTMLDOC builder for setting HTMLDOC-related properties.
386    */
387   public HtmlDocBuilder getHtmlDocBuilder() {
388      return htmlDocBuilder;
389   }
390
391   /**
392    * Creates a new {@link PropertyStore} object initialized with the properties defined in this config.
393    *
394    * @return A new property store.
395    */
396   protected PropertyStoreBuilder createPropertyStore() {
397      return PropertyStore.create().add(properties);
398   }
399
400
401   //----------------------------------------------------------------------------------------------------
402   // Methods that give access to the config file, var resolver, and properties.
403   //----------------------------------------------------------------------------------------------------
404
405   /**
406    * Returns the external configuration file for this resource.
407    *
408    * <p>
409    * The configuration file location is determined via the {@link RestResource#config() @RestResource(config)}
410    * annotation on the resource.
411    *
412    * <p>
413    * The config file can be programmatically overridden by adding the following method to your resource:
414    * <p class='bcode w800'>
415    *    <jk>public</jk> Config createConfig(ServletConfig servletConfig) <jk>throws</jk> ServletException;
416    * </p>
417    *
418    * <p>
419    * If a config file is not set up, then an empty config file will be returned that is not backed by any file.
420    *
421    * @return The external config file for this resource.  Never <jk>null</jk>.
422    */
423   public Config getConfig() {
424      return config;
425   }
426
427   /**
428    * Returns the configuration properties for this resource.
429    *
430    * <p>
431    * The configuration properties are determined via the {@link RestResource#properties() @RestResource(properties)} annotation on the resource.
432    *
433    * <p>
434    * The configuration properties can be augmented programmatically by adding the following method to your resource:
435    * <p class='bcode w800'>
436    *    <jk>public</jk> RestContextProperties createProperties(ServletConfig servletConfig) <jk>throws</jk> ServletException;
437    * </p>
438    *
439    * <p>
440    * These properties can be modified during servlet initialization.
441    * However, any modifications made after {@link RestServlet#init(ServletConfig)} has been called will have no effect.
442    *
443    * @return The configuration properties for this resource.  Never <jk>null</jk>.
444    */
445   public RestContextProperties getProperties() {
446      return properties;
447   }
448
449   /**
450    * Creates the variable resolver for this resource.
451    *
452    * <p>
453    * The variable resolver returned by this method can resolve the following variables:
454    * <ul>
455    *    <li>{@link SystemPropertiesVar}
456    *    <li>{@link EnvVariablesVar}
457    *    <li>{@link ConfigVar}
458    *    <li>{@link IfVar}
459    *    <li>{@link SwitchVar}
460    * </ul>
461    *
462    * <p>
463    * Note that the variables supported here are only a subset of those returned by
464    * {@link RestRequest#getVarResolverSession()}.
465    *
466    * @return The variable resolver for this resource.  Never <jk>null</jk>.
467    */
468   public VarResolverBuilder getVarResolverBuilder() {
469      return varResolverBuilder;
470   }
471
472
473   //----------------------------------------------------------------------------------------------------
474   // Properties
475   //----------------------------------------------------------------------------------------------------
476
477   /**
478    * Configuration property:  Allow body URL parameter.
479    *
480    * <p>
481    * When enabled, the HTTP body content on PUT and POST requests can be passed in as text using the <js>"body"</js>
482    * URL parameter.
483    * <br>
484    * For example:
485    * <p class='bcode w800'>
486    *  ?body=(name='John%20Smith',age=45)
487    * </p>
488    *
489    * <h5 class='section'>See Also:</h5>
490    * <ul>
491    *    <li class='jf'>{@link RestContext#REST_allowBodyParam}
492    * </ul>
493    *
494    * @param value
495    *    The new value for this setting.
496    *    <br>The default is <jk>true</jk>.
497    * @return This object (for method chaining).
498    */
499   public RestContextBuilder allowBodyParam(boolean value) {
500      return set(REST_allowBodyParam, value);
501   }
502
503   /**
504    * Configuration property:  Allowed method parameters.
505    *
506    * <p>
507    * When specified, the HTTP method can be overridden by passing in a <js>"method"</js> URL parameter on a regular
508    * GET request.
509    * <br>
510    * For example:
511    * <p class='bcode w800'>
512    *  ?method=OPTIONS
513    * </p>
514    *
515    * <h5 class='section'>See Also:</h5>
516    * <ul>
517    *    <li class='jf'>{@link RestContext#REST_allowedMethodParams}
518    * </ul>
519    *
520    * @param value
521    *    The new value for this setting.
522    *    <br>The default is <code>[<js>"HEAD"</js>,<js>"OPTIONS"</js>]</code>.
523    *    <br>Individual values can also be comma-delimited lists.
524    * @return This object (for method chaining).
525    */
526   public RestContextBuilder allowedMethodParams(String...value) {
527      return set(REST_allowedMethodParams, StringUtils.join(value, ','));
528   }
529
530   /**
531    * Configuration property:  Allow header URL parameters.
532    *
533    * <p>
534    * When enabled, headers such as <js>"Accept"</js> and <js>"Content-Type"</js> to be passed in as URL query
535    * parameters.
536    * <br>
537    * For example:
538    * <p class='bcode w800'>
539    *  ?Accept=text/json&amp;Content-Type=text/json
540    * </p>
541    *
542    * <h5 class='section'>See Also:</h5>
543    * <ul>
544    *    <li class='jf'>{@link RestContext#REST_allowHeaderParams}
545    * </ul>
546    *
547    * @param value
548    *    The new value for this setting.
549    *    <br>The default is <jk>true</jk>.
550    * @return This object (for method chaining).
551    */
552   public RestContextBuilder allowHeaderParams(boolean value) {
553      return set(REST_allowHeaderParams, value);
554   }
555
556   /**
557    * Configuration property:  REST call handler.
558    *
559    * <p>
560    * This class handles the basic lifecycle of an HTTP REST call.
561    * <br>Subclasses can be used to customize how these HTTP calls are handled.
562    *
563    * <h5 class='section'>See Also:</h5>
564    * <ul>
565    *    <li class='jf'>{@link RestContext#REST_callHandler}
566    * </ul>
567    *
568    * @param value
569    *    The new value for this setting.
570    *    <br>The default is {@link BasicRestCallHandler}.
571    * @return This object (for method chaining).
572    */
573   public RestContextBuilder callHandler(Class<? extends RestCallHandler> value) {
574      return set(REST_callHandler, value);
575   }
576
577   /**
578    * Configuration property:  REST call handler.
579    *
580    * <p>
581    * Same as {@link #callHandler(Class)} except input is a pre-constructed instance.
582    *
583    * <h5 class='section'>See Also:</h5>
584    * <ul>
585    *    <li class='jf'>{@link RestContext#REST_callHandler}
586    * </ul>
587    *
588    * @param value
589    *    The new value for this setting.
590    *    <br>The default is {@link BasicRestCallHandler}.
591    * @return This object (for method chaining).
592    */
593   public RestContextBuilder callHandler(RestCallHandler value) {
594      return set(REST_callHandler, value);
595   }
596
597   /**
598    * Configuration property:  Children.
599    *
600    * <p>
601    * Defines children of this resource.
602    *
603    * <p>
604    * A REST child resource is simply another servlet that is initialized as part of the parent resource and has a
605    * servlet path directly under the parent servlet path.
606    *
607    * <h5 class='section'>See Also:</h5>
608    * <ul>
609    *    <li class='jf'>{@link RestContext#REST_children}
610    * </ul>
611    *
612    * @param values The values to add to this setting.
613    * @return This object (for method chaining).
614    */
615   public RestContextBuilder children(Class<?>...values) {
616      return addTo(REST_children, values);
617   }
618
619   /**
620    * Configuration property:  Children.
621    *
622    * <p>
623    * Same as {@link #children(Class...)} except input is pre-constructed instances.
624    *
625    * <h5 class='section'>See Also:</h5>
626    * <ul>
627    *    <li class='jf'>{@link RestContext#REST_children}
628    * </ul>
629    *
630    * @param values The values to add to this setting.
631    * @return This object (for method chaining).
632    */
633   public RestContextBuilder children(Object...values) {
634      return addTo(REST_children, values);
635   }
636
637   /**
638    * Configuration property:  Children.
639    *
640    * <p>
641    * Shortcut for adding a single child to this resource.
642    *
643    * <p>
644    * This can be used for resources that don't have a {@link RestResource#path() @RestResource(path)} annotation.
645    *
646    * <h5 class='section'>See Also:</h5>
647    * <ul>
648    *    <li class='jf'>{@link RestContext#REST_children}
649    * </ul>
650    *
651    * @param path The child path relative to the parent resource URI.
652    * @param child The child to add to this resource.
653    * @return This object (for method chaining).
654    */
655   public RestContextBuilder child(String path, Object child) {
656      return addTo(REST_children, new RestChild(path, child));
657   }
658
659   /**
660    * Configuration property:  Classpath resource finder.
661    *
662    * <p>
663    * Used to retrieve localized files from the classpath.
664    *
665    * <h5 class='section'>See Also:</h5>
666    * <ul>
667    *    <li class='jf'>{@link RestContext#REST_classpathResourceFinder}
668    * </ul>
669    *
670    * @param value
671    *    The new value for this setting.
672    *    <br>The default is {@link ClasspathResourceFinderBasic}.
673    * @return This object (for method chaining).
674    */
675   public RestContextBuilder classpathResourceFinder(Class<? extends ClasspathResourceFinder> value) {
676      return set(REST_classpathResourceFinder, value);
677   }
678
679   /**
680    * Configuration property:  Classpath resource finder.
681    *
682    * <p>
683    * Same as {@link #classpathResourceFinder(ClasspathResourceFinder)} except input is a pre-constructed instance.
684    *
685    * <h5 class='section'>See Also:</h5>
686    * <ul>
687    *    <li class='jf'>{@link RestContext#REST_classpathResourceFinder}
688    * </ul>
689    *
690    * @param value
691    *    The new value for this setting.
692    *    <br>The default is {@link ClasspathResourceFinderBasic}.
693    * @return This object (for method chaining).
694    */
695   public RestContextBuilder classpathResourceFinder(ClasspathResourceFinder value) {
696      return set(REST_classpathResourceFinder, value);
697   }
698
699   /**
700    * Configuration property:  Client version header.
701    *
702    * <p>
703    * Specifies the name of the header used to denote the client version on HTTP requests.
704    *
705    * <p>
706    * The client version is used to support backwards compatibility for breaking REST interface changes.
707    * <br>Used in conjunction with {@link RestMethod#clientVersion() @RestMethod(clientVersion)} annotation.
708    *
709    * <h5 class='section'>See Also:</h5>
710    * <ul>
711    *    <li class='jf'>{@link RestContext#REST_clientVersionHeader}
712    * </ul>
713    *
714    * @param value
715    *    The new value for this setting.
716    *    <br>The default is <js>"X-Client-Version"</js>.
717    * @return This object (for method chaining).
718    */
719   public RestContextBuilder clientVersionHeader(String value) {
720      return set(REST_clientVersionHeader, value);
721   }
722
723   /**
724    * Configuration property:  Class-level response converters.
725    *
726    * <p>
727    * Associates one or more {@link RestConverter converters} with a resource class.
728    *
729    * <h5 class='section'>See Also:</h5>
730    * <ul>
731    *    <li class='jf'>{@link RestContext#REST_converters}
732    * </ul>
733    *
734    * @param values The values to add to this setting.
735    * @return This object (for method chaining).
736    */
737   public RestContextBuilder converters(Class<?>...values) {
738      return addTo(REST_converters, values);
739   }
740
741   /**
742    * Configuration property:  Response converters.
743    *
744    * <p>
745    * Same as {@link #converters(Class...)} except input is pre-constructed instances.
746    *
747    * <h5 class='section'>See Also:</h5>
748    * <ul>
749    *    <li class='jf'>{@link RestContext#REST_converters}
750    * </ul>
751    *
752    * @param values The values to add to this setting.
753    * @return This object (for method chaining).
754    */
755   public RestContextBuilder converters(RestConverter...values) {
756      return addTo(REST_converters, values);
757   }
758
759   /**
760    * Configuration property:  Debug mode.
761    *
762    * <h5 class='section'>See Also:</h5>
763    * <ul>
764    *    <li class='jf'>{@link RestContext#REST_debug}
765    *    <li class='jf'>{@link BeanContext#BEAN_debug}
766    * </ul>
767    *
768    * @param value The new value for this setting.
769    * @return This object (for method chaining).
770    */
771   @Override
772   public RestContextBuilder debug(boolean value) {
773      super.debug(value);
774      return set(REST_debug, value);
775   }
776
777   /**
778    * Configuration property:  Default character encoding.
779    *
780    * <p>
781    * The default character encoding for the request and response if not specified on the request.
782    *
783    * <h5 class='section'>See Also:</h5>
784    * <ul>
785    *    <li class='jf'>{@link RestContext#REST_defaultCharset}
786    * </ul>
787    *
788    * @param value
789    *    The new value for this setting.
790    *    <br>The default is <js>"utf-8"</js>.
791    * @return This object (for method chaining).
792    */
793   public RestContextBuilder defaultCharset(String value) {
794      return set(REST_defaultCharset, value);
795   }
796
797   /**
798    * Configuration property:  Default character encoding.
799    *
800    * <p>
801    * Same as {@link #defaultCharset(Charset)} but takes in an instance of {@link Charset}.
802    *
803    * <h5 class='section'>See Also:</h5>
804    * <ul>
805    *    <li class='jf'>{@link RestContext#REST_defaultCharset}
806    * </ul>
807    *
808    * @param value
809    *    The new value for this setting.
810    *    <br>The default is <js>"utf-8"</js>.
811    * @return This object (for method chaining).
812    */
813   public RestContextBuilder defaultCharset(Charset value) {
814      return set(REST_defaultCharset, value);
815   }
816
817   /**
818    * Configuration property:  Default request headers.
819    *
820    * <p>
821    * Specifies default values for request headers if they're not passed in through the request.
822    *
823    * <h5 class='section'>See Also:</h5>
824    * <ul>
825    *    <li class='jf'>{@link RestContext#REST_defaultRequestHeaders}
826    * </ul>
827    *
828    * @param headers The headers in the format <js>"Header-Name: header-value"</js>.
829    * @return This object (for method chaining).
830    * @throws RestServletException If malformed header is found.
831    */
832   public RestContextBuilder defaultRequestHeaders(String...headers) throws RestServletException {
833      for (String header : headers) {
834         String[] h = RestUtils.parseHeader(header);
835         if (h == null)
836            throw new RestServletException("Invalid default request header specified: ''{0}''.  Must be in the format: ''Header-Name: header-value''", header);
837         defaultRequestHeader(h[0], h[1]);
838      }
839      return this;
840   }
841
842   /**
843    * Specifies a default <code>Accept</code> header value if not specified on a request.
844    *
845    * @param value
846    *    The default value of the <code>Accept</code> header.
847    *    <br>Ignored if <jk>null</jk> or empty.
848    * @return This object (for method chaining).
849    */
850   public RestContextBuilder defaultAccept(String value) {
851      if (isNotEmpty(value))
852         defaultRequestHeader("Accept", value);
853      return this;
854   }
855
856   /**
857    * Specifies a default <code>Content-Type</code> header value if not specified on a request.
858    *
859    * @param value
860    *    The default value of the <code>Content-Type</code> header.
861    *    <br>Ignored if <jk>null</jk> or empty.
862    * @return This object (for method chaining).
863    */
864   public RestContextBuilder defaultContentType(String value) {
865      if (isNotEmpty(value))
866         defaultRequestHeader("Content-Type", value);
867      return this;
868   }
869
870   /**
871    * Configuration property:  Default request headers.
872    *
873    * <p>
874    * Same as {@link #defaultRequestHeaders(String...)} but adds a single header name/value pair.
875    *
876    * <h5 class='section'>See Also:</h5>
877    * <ul>
878    *    <li class='jf'>{@link RestContext#REST_defaultRequestHeaders}
879    * </ul>
880    *
881    * @param name The HTTP header name.
882    * @param value The HTTP header value.
883    * @return This object (for method chaining).
884    */
885   public RestContextBuilder defaultRequestHeader(String name, Object value) {
886      return addTo(REST_defaultRequestHeaders, name, value);
887   }
888
889   /**
890    * Configuration property:  Default response headers.
891    *
892    * <p>
893    * Specifies default values for response headers if they're not set after the Java REST method is called.
894    *
895    * <h5 class='section'>See Also:</h5>
896    * <ul>
897    *    <li class='jf'>{@link RestContext#REST_defaultResponseHeaders}
898    * </ul>
899    *
900    * @param headers The headers in the format <js>"Header-Name: header-value"</js>.
901    * @return This object (for method chaining).
902    * @throws RestServletException If malformed header is found.
903    */
904   public RestContextBuilder defaultResponseHeaders(String...headers) throws RestServletException {
905      for (String header : headers) {
906         String[] h = RestUtils.parseHeader(header);
907         if (h == null)
908            throw new RestServletException("Invalid default response header specified: ''{0}''.  Must be in the format: ''Header-Name: header-value''", header);
909         defaultResponseHeader(h[0], h[1]);
910      }
911      return this;
912   }
913
914   /**
915    * Configuration property:  Default response headers.
916    *
917    * <p>
918    * Same as {@link #defaultResponseHeaders(String...)} but adds a single header name/value pair.
919    *
920    * <h5 class='section'>See Also:</h5>
921    * <ul>
922    *    <li class='jf'>{@link RestContext#REST_defaultResponseHeaders}
923    * </ul>
924    *
925    * @param name The HTTP header name.
926    * @param value The HTTP header value.
927    * @return This object (for method chaining).
928    */
929   public RestContextBuilder defaultResponseHeader(String name, Object value) {
930      return addTo(REST_defaultResponseHeaders, name, value);
931   }
932
933   /**
934    * Configuration property:  Compression encoders.
935    *
936    * <p>
937    * These can be used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses.
938    *
939    * <h5 class='section'>See Also:</h5>
940    * <ul>
941    *    <li class='jf'>{@link RestContext#REST_encoders}
942    * </ul>
943    *
944    * @param values The values to add to this setting.
945    * @return This object (for method chaining).
946    */
947   public RestContextBuilder encoders(Class<?>...values) {
948      return addTo(REST_encoders, values);
949   }
950
951   /**
952    * Configuration property:  Compression encoders.
953    *
954    * <p>
955    * Same as {@link #encoders(Class...)} except input a pre-constructed instances.
956    *
957    * <h5 class='section'>See Also:</h5>
958    * <ul>
959    *    <li class='jf'>{@link RestContext#REST_encoders}
960    * </ul>
961    *
962    * @param values The values to add to this setting.
963    * @return This object (for method chaining).
964    */
965   public RestContextBuilder encoders(Encoder...values) {
966      return addTo(REST_encoders, values);
967   }
968
969   /**
970    * Configuration property:  Class-level guards.
971    *
972    * <p>
973    * Associates one or more {@link RestGuard RestGuards} with all REST methods defined in this class.
974    *
975    * <h5 class='section'>See Also:</h5>
976    * <ul>
977    *    <li class='jf'>{@link RestContext#REST_guards}
978    * </ul>
979    *
980    * @param values The values to add to this setting.
981    * @return This object (for method chaining).
982    */
983   public RestContextBuilder guards(Class<?>...values) {
984      return addTo(REST_guards, values);
985   }
986
987   /**
988    * Configuration property:  Class-level guards.
989    *
990    * <p>
991    * Same as {@link #guards(Class...)} except input is pre-constructed instances.
992    *
993    * <h5 class='section'>See Also:</h5>
994    * <ul>
995    *    <li class='jf'>{@link RestContext#REST_guards}
996    * </ul>
997    *
998    * @param values The values to add to this setting.
999    * @return This object (for method chaining).
1000    */
1001   public RestContextBuilder guards(RestGuard...values) {
1002      return addTo(REST_guards, values);
1003   }
1004
1005   /**
1006    * Configuration property:  REST info provider.
1007    *
1008    * <p>
1009    * Class used to retrieve title/description/swagger information about a resource.
1010    *
1011    * <h5 class='section'>See Also:</h5>
1012    * <ul>
1013    *    <li class='jf'>{@link RestContext#REST_infoProvider}
1014    * </ul>
1015    *
1016    * @param value
1017    *    The new value for this setting.
1018    *    <br>The default is {@link BasicRestInfoProvider}.
1019    * @return This object (for method chaining).
1020    */
1021   public RestContextBuilder infoProvider(Class<? extends RestInfoProvider> value) {
1022      return set(REST_infoProvider, value);
1023   }
1024
1025   /**
1026    * Configuration property:  REST info provider.
1027    *
1028    * <p>
1029    * Same as {@link #infoProvider(Class)} except input is a pre-constructed instance.
1030    *
1031    * <h5 class='section'>See Also:</h5>
1032    * <ul>
1033    *    <li class='jf'>{@link RestContext#REST_infoProvider}
1034    * </ul>
1035    *
1036    * @param value
1037    *    The new value for this setting.
1038    *    <br>The default is {@link BasicRestInfoProvider}.
1039    * @return This object (for method chaining).
1040    */
1041   public RestContextBuilder infoProvider(RestInfoProvider value) {
1042      return set(REST_infoProvider, value);
1043   }
1044
1045   /**
1046    * Configuration property:  REST logger.
1047    *
1048    * <p>
1049    * Specifies the logger to use for logging.
1050    *
1051    * <h5 class='section'>See Also:</h5>
1052    * <ul>
1053    *    <li class='jf'>{@link RestContext#REST_logger}
1054    * </ul>
1055    *
1056    * @param value
1057    *    The new value for this setting.
1058    *    <br>The default is {@link BasicRestLogger}.
1059    *    <br>Can be <jk>null</jk> to disable logging.
1060    * @return This object (for method chaining).
1061    */
1062   public RestContextBuilder logger(Class<? extends RestLogger> value) {
1063      return set(REST_logger, value);
1064   }
1065
1066   /**
1067    * Configuration property:  REST logger.
1068    *
1069    * <p>
1070    * Same as {@link #logger(Class)} except input is a pre-constructed instance.
1071    *
1072    * <h5 class='section'>See Also:</h5>
1073    * <ul>
1074    *    <li class='jf'>{@link RestContext#REST_logger}
1075    * </ul>
1076    *
1077    * @param value
1078    *    The new value for this setting.
1079    *    <br>The default is {@link BasicRestLogger}.
1080    *    <br>Can be <jk>null</jk> to disable logging.
1081    * @return This object (for method chaining).
1082    */
1083   public RestContextBuilder logger(RestLogger value) {
1084      return set(REST_logger, value);
1085   }
1086
1087   /**
1088    * Configuration property:  The maximum allowed input size (in bytes) on HTTP requests.
1089    *
1090    * <p>
1091    * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting
1092    * in out-of-memory errors which could affect system stability.
1093    *
1094    * <h5 class='section'>See Also:</h5>
1095    * <ul>
1096    *    <li class='jf'>{@link RestContext#REST_maxInput}
1097    * </ul>
1098    *
1099    * @param value
1100    *    The new value for this setting.
1101    *    <br>The default is <js>"100M"</js>.
1102    * @return This object (for method chaining).
1103    */
1104   public RestContextBuilder maxInput(String value) {
1105      return set(REST_maxInput, value);
1106   }
1107
1108   /**
1109    * Configuration property:  Messages.
1110    *
1111    * <p>
1112    * Identifies the location of the resource bundle for this class.
1113    *
1114    * <h5 class='section'>See Also:</h5>
1115    * <ul>
1116    *    <li class='jf'>{@link RestContext#REST_messages}
1117    * </ul>
1118    *
1119    * @param values The values to add to this setting.
1120    * @return This object (for method chaining).
1121    */
1122   public RestContextBuilder messages(MessageBundleLocation...values) {
1123      return addTo(REST_messages, values);
1124   }
1125
1126   /**
1127    * Configuration property:  Messages.
1128    *
1129    * <p>
1130    * Same as {@link #messages(MessageBundleLocation...)} except allows you to pass in the base class and bundle
1131    * path separately.
1132    *
1133    * <h5 class='section'>See Also:</h5>
1134    * <ul>
1135    *    <li class='jf'>{@link RestContext#REST_messages}
1136    * </ul>
1137    *
1138    * @param baseClass
1139    *    The base class that the bundle path is relative to.
1140    *    <br>If <jk>null</jk>, assumed to be the resource class itself.
1141    * @param bundlePath The bundle path relative to the base class.
1142    * @return This object (for method chaining).
1143    */
1144   public RestContextBuilder messages(Class<?> baseClass, String bundlePath) {
1145      return addTo(REST_messages, new MessageBundleLocation(baseClass, bundlePath));
1146   }
1147
1148   /**
1149    * Configuration property:  Messages.
1150    *
1151    * <p>
1152    * Same as {@link #messages(Class,String)} except assumes the base class is the resource class itself.
1153    *
1154    * <h5 class='section'>See Also:</h5>
1155    * <ul>
1156    *    <li class='jf'>{@link RestContext#REST_messages}
1157    * </ul>
1158    *
1159    * @param bundlePath The bundle path relative to the base class.
1160    * @return This object (for method chaining).
1161    */
1162   public RestContextBuilder messages(String bundlePath) {
1163      return addTo(REST_messages, new MessageBundleLocation(null, bundlePath));
1164   }
1165
1166   /**
1167    * Configuration property:  MIME types.
1168    *
1169    * <p>
1170    * Defines MIME-type file type mappings.
1171    *
1172    * <h5 class='section'>See Also:</h5>
1173    * <ul>
1174    *    <li class='jf'>{@link RestContext#REST_mimeTypes}
1175    * </ul>
1176    *
1177    * @param values The values to add to this setting.
1178    * @return This object (for method chaining).
1179    */
1180   public RestContextBuilder mimeTypes(String...values) {
1181      return addTo(REST_mimeTypes, values);
1182   }
1183
1184   /**
1185    * Configuration property:  Java method parameter resolvers.
1186    *
1187    * <p>
1188    * By default, the Juneau framework will automatically Java method parameters of various types (e.g.
1189    * <code>RestRequest</code>, <code>Accept</code>, <code>Reader</code>).
1190    * This annotation allows you to provide your own resolvers for your own class types that you want resolved.
1191    *
1192    * <h5 class='section'>See Also:</h5>
1193    * <ul>
1194    *    <li class='jf'>{@link RestContext#REST_paramResolvers}
1195    * </ul>
1196    *
1197    * @param values The values to add to this setting.
1198    * @return This object (for method chaining).
1199    */
1200   @SuppressWarnings("unchecked")
1201   public RestContextBuilder paramResolvers(Class<? extends RestMethodParam>...values) {
1202      return addTo(REST_paramResolvers, values);
1203   }
1204
1205   /**
1206    * Configuration property:  Java method parameter resolvers.
1207    *
1208    * <p>
1209    * Same as {@link #paramResolvers(Class...)} except input is pre-constructed instances.
1210    *
1211    * <h5 class='section'>See Also:</h5>
1212    * <ul>
1213    *    <li class='jf'>{@link RestContext#REST_paramResolvers}
1214    * </ul>
1215    *
1216    * @param values The values to add to this setting.
1217    * @return This object (for method chaining).
1218    */
1219   public RestContextBuilder paramResolvers(RestMethodParam...values) {
1220      return addTo(REST_paramResolvers, values);
1221   }
1222
1223   /**
1224    * Configuration property:  Parser listener.
1225    *
1226    * <p>
1227    * Specifies the parser listener class to use for listening to non-fatal parsing errors.
1228    *
1229    * <h5 class='section'>See Also:</h5>
1230    * <ul>
1231    *    <li class='jf'>{@link Parser#PARSER_listener}
1232    * </ul>
1233    *
1234    * @param value The new value for this setting.
1235    * @return This object (for method chaining).
1236    */
1237   public RestContextBuilder parserListener(Class<? extends ParserListener> value) {
1238      if (value != ParserListener.Null.class)
1239         set(PARSER_listener, value);
1240      return this;
1241   }
1242
1243   /**
1244    * Configuration property:  Parsers.
1245    *
1246    * <p>
1247    * Adds class-level parsers to this resource.
1248    *
1249    * <h5 class='section'>See Also:</h5>
1250    * <ul>
1251    *    <li class='jf'>{@link RestContext#REST_parsers}
1252    * </ul>
1253    *
1254    * @param values The values to add to this setting.
1255    * @return This object (for method chaining).
1256    */
1257   public RestContextBuilder parsers(Class<?>...values) {
1258      return addTo(REST_parsers, values);
1259   }
1260
1261   /**
1262    * Configuration property:  Parsers.
1263    *
1264    * <p>
1265    * Same as {@link #parsers(Class...)} except allows you to overwrite the previous value.
1266    *
1267    * <h5 class='section'>See Also:</h5>
1268    * <ul>
1269    *    <li class='jf'>{@link RestContext#REST_parsers}
1270    * </ul>
1271    *
1272    * @param append
1273    *    If <jk>true</jk>, append to the existing list, otherwise overwrite the previous value.
1274    * @param values The values to add to this setting.
1275    * @return This object (for method chaining).
1276    */
1277   public RestContextBuilder parsers(boolean append, Object...values) {
1278      return set(append, REST_parsers, values);
1279   }
1280
1281   /**
1282    * Configuration property:  Parsers.
1283    *
1284    * <p>
1285    * Same as {@link #parsers(Class...)} except input is pre-constructed instances.
1286    *
1287    * <p>
1288    * Parser instances are considered set-in-stone and do NOT inherit properties and transforms defined on the
1289    * resource class or method.
1290    *
1291    * <h5 class='section'>See Also:</h5>
1292    * <ul>
1293    *    <li class='jf'>{@link RestContext#REST_parsers}
1294    * </ul>
1295    *
1296    * @param values The values to add to this setting.
1297    * @return This object (for method chaining).
1298    */
1299   public RestContextBuilder parsers(Object...values) {
1300      return addTo(REST_parsers, values);
1301   }
1302
1303   /**
1304    * Configuration property:  HTTP part parser.
1305    *
1306    * <p>
1307    * Specifies the {@link HttpPartParser} to use for parsing headers, query/form parameters, and URI parts.
1308    *
1309    * <h5 class='section'>See Also:</h5>
1310    * <ul>
1311    *    <li class='jf'>{@link RestContext#REST_partParser}
1312    * </ul>
1313    *
1314    * @param value
1315    *    The new value for this setting.
1316    *    <br>The default is {@link OpenApiParser}.
1317    * @return This object (for method chaining).
1318    */
1319   public RestContextBuilder partParser(Class<? extends HttpPartParser> value) {
1320      if (value != HttpPartParser.Null.class)
1321         set(REST_partParser, value);
1322      return this;
1323   }
1324
1325   /**
1326    * Configuration property:  HTTP part parser.
1327    *
1328    * <p>
1329    * Same as {@link #partParser(Class)} except input is a pre-constructed instance.
1330    *
1331    * <h5 class='section'>See Also:</h5>
1332    * <ul>
1333    *    <li class='jf'>{@link RestContext#REST_partParser}
1334    * </ul>
1335    *
1336    * @param value
1337    *    The new value for this setting.
1338    *    <br>The default is {@link OpenApiParser}.
1339    * @return This object (for method chaining).
1340    */
1341   public RestContextBuilder partParser(HttpPartParser value) {
1342      return set(REST_partParser, value);
1343   }
1344
1345   /**
1346    * Configuration property:  HTTP part serializer.
1347    *
1348    * <p>
1349    * Specifies the {@link HttpPartSerializer} to use for serializing headers, query/form parameters, and URI parts.
1350    *
1351    * <h5 class='section'>See Also:</h5>
1352    * <ul>
1353    *    <li class='jf'>{@link RestContext#REST_partSerializer}
1354    * </ul>
1355    *
1356    * @param value
1357    *    The new value for this setting.
1358    *    <br>The default is {@link OpenApiSerializer}.
1359    * @return This object (for method chaining).
1360    */
1361   public RestContextBuilder partSerializer(Class<? extends HttpPartSerializer> value) {
1362      if (value != HttpPartSerializer.Null.class)
1363         set(REST_partSerializer, value);
1364      return this;
1365   }
1366
1367   /**
1368    * Configuration property:  HTTP part serializer.
1369    *
1370    * <p>
1371    * Same as {@link #partSerializer(Class)} except input is a pre-constructed instance.
1372    *
1373    * <h5 class='section'>See Also:</h5>
1374    * <ul>
1375    *    <li class='jf'>{@link RestContext#REST_partSerializer}
1376    * </ul>
1377    *
1378    * @param value
1379    *    The new value for this setting.
1380    *    <br>The default is {@link OpenApiSerializer}.
1381    * @return This object (for method chaining).
1382    */
1383   public RestContextBuilder partSerializer(HttpPartSerializer value) {
1384      return set(REST_partSerializer, value);
1385   }
1386
1387   /**
1388    * Configuration property:  Resource path.
1389    *
1390    * <p>
1391    * Identifies the URL subpath relative to the parent resource.
1392    *
1393    * <h5 class='section'>See Also:</h5>
1394    * <ul>
1395    *    <li class='jf'>{@link RestContext#REST_path}
1396    * </ul>
1397    *
1398    * @param value The new value for this setting.
1399    * @return This object (for method chaining).
1400    */
1401   public RestContextBuilder path(String value) {
1402      if (startsWith(value, '/'))
1403         value = value.substring(1);
1404      this.path = value;
1405      return this;
1406   }
1407
1408   /**
1409    * Configuration property:  Render response stack traces in responses.
1410    *
1411    * <p>
1412    * Render stack traces in HTTP response bodies when errors occur.
1413    *
1414    * <h5 class='section'>See Also:</h5>
1415    * <ul>
1416    *    <li class='jf'>{@link RestContext#REST_renderResponseStackTraces}
1417    * </ul>
1418    *
1419    * @param value
1420    *    The new value for this setting.
1421    *    <br>The default is <jk>false</jk>.
1422    * @return This object (for method chaining).
1423    */
1424   public RestContextBuilder renderResponseStackTraces(boolean value) {
1425      return set(REST_renderResponseStackTraces, value);
1426   }
1427
1428   /**
1429    * Configuration property:  Render response stack traces in responses.
1430    *
1431    * <p>
1432    * Shortcut for calling <code>renderResponseStackTraces(<jk>true</jk>)</code>.
1433    *
1434    * <h5 class='section'>See Also:</h5>
1435    * <ul>
1436    *    <li class='jf'>{@link RestContext#REST_renderResponseStackTraces}
1437    * </ul>
1438    *
1439    * @return This object (for method chaining).
1440    */
1441   public RestContextBuilder renderResponseStackTraces() {
1442      return set(REST_renderResponseStackTraces, true);
1443   }
1444
1445   /**
1446    * REST resource resolver.
1447    *
1448    * <p>
1449    * The resolver used for resolving child resources.
1450    *
1451    * <p>
1452    * Can be used to provide customized resolution of REST resource class instances (e.g. resources retrieve from Spring).
1453    *
1454    * <h5 class='section'>See Also:</h5>
1455    * <ul>
1456    *    <li class='jf'>{@link RestContext#REST_resourceResolver}
1457    * </ul>
1458    *
1459    * @param value
1460    *    The new value for this setting.
1461    *    <br>The default is {@link BasicRestResourceResolver}.
1462    * @return This object (for method chaining).
1463    */
1464   public RestContextBuilder resourceResolver(Class<? extends RestResourceResolver> value) {
1465      return set(REST_resourceResolver, value);
1466   }
1467
1468   /**
1469    * REST resource resolver.
1470    *
1471    * <p>
1472    * Same as {@link #resourceResolver(Class)} except input is a pre-constructed instance.
1473    *
1474    * <h5 class='section'>See Also:</h5>
1475    * <ul>
1476    *    <li class='jf'>{@link RestContext#REST_resourceResolver}
1477    * </ul>
1478    *
1479    * @param value
1480    *    The new value for this setting.
1481    *    <br>The default is {@link BasicRestResourceResolver}.
1482    * @return This object (for method chaining).
1483    */
1484   public RestContextBuilder resourceResolver(RestResourceResolver value) {
1485      return set(REST_resourceResolver, value);
1486   }
1487
1488   /**
1489    * Configuration property:  Response handlers.
1490    *
1491    * <p>
1492    * Specifies a list of {@link ResponseHandler} classes that know how to convert POJOs returned by REST methods or
1493    * set via {@link RestResponse#setOutput(Object)} into appropriate HTTP responses.
1494    *
1495    * <h5 class='section'>See Also:</h5>
1496    * <ul>
1497    *    <li class='jf'>{@link RestContext#REST_responseHandlers}
1498    * </ul>
1499    *
1500    * @param values The values to add to this setting.
1501    * @return This object (for method chaining).
1502    */
1503   public RestContextBuilder responseHandlers(Class<?>...values) {
1504      return addTo(REST_responseHandlers, values);
1505   }
1506
1507   /**
1508    * Configuration property:  Response handlers.
1509    *
1510    * <p>
1511    * Same as {@link #responseHandlers(Class...)} except input is pre-constructed instances.
1512    *
1513    * <h5 class='section'>See Also:</h5>
1514    * <ul>
1515    *    <li class='jf'>{@link RestContext#REST_responseHandlers}
1516    * </ul>
1517    *
1518    * @param values The values to add to this setting.
1519    * @return This object (for method chaining).
1520    */
1521   public RestContextBuilder responseHandlers(ResponseHandler...values) {
1522      return addTo(REST_responseHandlers, values);
1523   }
1524
1525   /**
1526    * Configuration property:  Serializer listener.
1527    *
1528    * <p>
1529    * Specifies the serializer listener class to use for listening to non-fatal serialization errors.
1530    *
1531    * <h5 class='section'>See Also:</h5>
1532    * <ul>
1533    *    <li class='jf'>{@link Serializer#SERIALIZER_listener}
1534    * </ul>
1535    *
1536    * @param value The new value for this setting.
1537    * @return This object (for method chaining).
1538    */
1539   public RestContextBuilder serializerListener(Class<? extends SerializerListener> value) {
1540      if (value != SerializerListener.Null.class)
1541         set(SERIALIZER_listener, value);
1542      return this;
1543   }
1544
1545   /**
1546    * Configuration property:  Serializers.
1547    *
1548    * <p>
1549    * Adds class-level serializers to this resource.
1550    *
1551    * <h5 class='section'>See Also:</h5>
1552    * <ul>
1553    *    <li class='jf'>{@link RestContext#REST_serializers}
1554    * </ul>
1555    *
1556    * @param values The values to add to this setting.
1557    * @return This object (for method chaining).
1558    */
1559   public RestContextBuilder serializers(Class<?>...values) {
1560      return addTo(REST_serializers, values);
1561   }
1562
1563   /**
1564    * Configuration property:  Serializers.
1565    *
1566    * <p>
1567    * Same as {@link #serializers(Class...)} except allows you to overwrite the previous value.
1568    *
1569    * <h5 class='section'>See Also:</h5>
1570    * <ul>
1571    *    <li class='jf'>{@link RestContext#REST_serializers}
1572    * </ul>
1573    *
1574    * @param append
1575    *    If <jk>true</jk>, append to the existing list, otherwise overwrite the previous value.
1576    * @param values The values to add to this setting.
1577    * @return This object (for method chaining).
1578    */
1579   public RestContextBuilder serializers(boolean append, Object...values) {
1580      return set(append, REST_serializers, values);
1581   }
1582
1583   /**
1584    * Configuration property:  Serializers.
1585    *
1586    * <p>
1587    * Same as {@link #serializers(Class...)} except input is pre-constructed instances.
1588    *
1589    * <p>
1590    * Serializer instances are considered set-in-stone and do NOT inherit properties and transforms defined on the
1591    * resource class or method.
1592    *
1593    * <h5 class='section'>See Also:</h5>
1594    * <ul>
1595    *    <li class='jf'>{@link RestContext#REST_serializers}
1596    * </ul>
1597    *
1598    * @param values The values to add to this setting.
1599    * @return This object (for method chaining).
1600    */
1601   public RestContextBuilder serializers(Object...values) {
1602      return addTo(REST_serializers, values);
1603   }
1604
1605   /**
1606    * Configuration property:  Static file response headers.
1607    *
1608    * <p>
1609    * Used to customize the headers on responses returned for statically-served files.
1610    *
1611    * <h5 class='section'>See Also:</h5>
1612    * <ul>
1613    *    <li class='jf'>{@link RestContext#REST_staticFileResponseHeaders}
1614    * </ul>
1615    *
1616    * @param append
1617    *    If <jk>true</jk>, append to the existing list, otherwise overwrite the previous value.
1618    * @param headers
1619    *    The headers to add to this list.
1620    *    <br>The default is <code>{<js>'Cache-Control'</js>: <js>'max-age=86400, public</js>}</code>.
1621    * @return This object (for method chaining).
1622    */
1623   public RestContextBuilder staticFileResponseHeaders(boolean append, Map<String,String> headers) {
1624      return set(append, REST_staticFileResponseHeaders, headers);
1625   }
1626
1627   /**
1628    * Configuration property:  Static file response headers.
1629    *
1630    * <p>
1631    * Same as {@link #staticFileResponseHeaders(boolean, Map)} with append=<jk>true</jk> except headers are strings
1632    * composed of key/value pairs.
1633    *
1634    * <h5 class='section'>See Also:</h5>
1635    * <ul>
1636    *    <li class='jf'>{@link RestContext#REST_staticFileResponseHeaders}
1637    * </ul>
1638    *
1639    * @param headers The headers in the format <js>"Header-Name: header-value"</js>.
1640    * @return This object (for method chaining).
1641    * @throws RestServletException If malformed header is found.
1642    */
1643   public RestContextBuilder staticFileResponseHeaders(String...headers) throws RestServletException {
1644      for (String header : headers) {
1645         String[] h = RestUtils.parseHeader(header);
1646         if (h == null)
1647            throw new RestServletException("Invalid static file response header specified: ''{0}''.  Must be in the format: ''Header-Name: header-value''", header);
1648         staticFileResponseHeader(h[0], h[1]);
1649      }
1650      return this;
1651   }
1652
1653   /**
1654    * Configuration property:  Static file response headers.
1655    *
1656    * <p>
1657    * Same as {@link #staticFileResponseHeaders(String...)} except header is broken into name/value pair.
1658    *
1659    * <h5 class='section'>See Also:</h5>
1660    * <ul>
1661    *    <li class='jf'>{@link RestContext#REST_staticFileResponseHeaders}
1662    * </ul>
1663    *
1664    * @param name The HTTP header name.
1665    * @param value The HTTP header value.
1666    * @return This object (for method chaining).
1667    */
1668   public RestContextBuilder staticFileResponseHeader(String name, String value) {
1669      return addTo(REST_staticFileResponseHeaders, name, value);
1670   }
1671
1672   /**
1673    * Configuration property:  Static file mappings.
1674    *
1675    * <p>
1676    * Used to define paths and locations of statically-served files such as images or HTML documents.
1677    *
1678    * <h5 class='section'>See Also:</h5>
1679    * <ul>
1680    *    <li class='jf'>{@link RestContext#REST_staticFiles}
1681    * </ul>
1682    *
1683    * @param values The values to append to this setting.
1684    * @return This object (for method chaining).
1685    */
1686   public RestContextBuilder staticFiles(StaticFileMapping...values) {
1687      return addTo(REST_staticFiles, values);
1688   }
1689
1690   /**
1691    * Configuration property:  Static file mappings.
1692    *
1693    * <p>
1694    * Same as {@link #staticFiles(StaticFileMapping...)} except input is in the form of a mapping string.
1695    *
1696    * <p>
1697    * Mapping string must be one of these formats:
1698    * <ul>
1699    *    <li><js>"path:location"</js> (e.g. <js>"foodocs:docs/foo"</js>)
1700    *    <li><js>"path:location:headers-json"</js> (e.g. <js>"foodocs:docs/foo:{'Cache-Control':'max-age=86400, public'}"</js>)
1701    * </ul>
1702    *
1703    * <h5 class='section'>See Also:</h5>
1704    * <ul>
1705    *    <li class='jf'>{@link RestContext#REST_staticFiles}
1706    * </ul>
1707    *
1708    * @param mappingString The static file mapping string.
1709    * @return This object (for method chaining).
1710    */
1711   public RestContextBuilder staticFiles(String mappingString) {
1712      return staticFiles(new StaticFileMapping(resourceClass, mappingString));
1713   }
1714
1715   /**
1716    * Configuration property:  Static file mappings.
1717    *
1718    * <p>
1719    * Same as {@link #staticFiles(String)} except overrides the base class for retrieving the resource.
1720    *
1721    * <p>
1722    * Mapping string must be one of these formats:
1723    * <ul>
1724    *    <li><js>"path:location"</js> (e.g. <js>"foodocs:docs/foo"</js>)
1725    *    <li><js>"path:location:headers-json"</js> (e.g. <js>"foodocs:docs/foo:{'Cache-Control':'max-age=86400, public'}"</js>)
1726    * </ul>
1727    *
1728    * <h5 class='section'>See Also:</h5>
1729    * <ul>
1730    *    <li class='jf'>{@link RestContext#REST_staticFiles}
1731    * </ul>
1732    *
1733    * @param baseClass
1734    *    Overrides the default class to use for retrieving the classpath resource.
1735    *    <br>If <jk>null<jk>, uses the REST resource class.
1736    * @param mappingString The static file mapping string.
1737    * @return This object (for method chaining).
1738    */
1739   public RestContextBuilder staticFiles(Class<?> baseClass, String mappingString) {
1740      if (isNotEmpty(mappingString))
1741         staticFiles(new StaticFileMapping(baseClass, mappingString));
1742      return this;
1743   }
1744
1745   /**
1746    * Configuration property:  Static file mappings.
1747    *
1748    * <p>
1749    * Same as {@link #staticFiles(String)} except path and location are already split values.
1750    *
1751    * <h5 class='section'>See Also:</h5>
1752    * <ul>
1753    *    <li class='jf'>{@link RestContext#REST_staticFiles}
1754    * </ul>
1755    *
1756    * @param path
1757    *    The mapped URI path.
1758    *    <br>Leading and trailing slashes are trimmed.
1759    * @param location
1760    *    The location relative to the resource class.
1761    *    <br>Leading and trailing slashes are trimmed.
1762    * @return This object (for method chaining).
1763    */
1764   public RestContextBuilder staticFiles(String path, String location) {
1765      return staticFiles(new StaticFileMapping(null, path, location, null));
1766   }
1767
1768   /**
1769    * Configuration property:  Static file mappings.
1770    *
1771    * <p>
1772    * Same as {@link #staticFiles(String,String)} except overrides the base class for retrieving the resource.
1773    *
1774    * <h5 class='section'>See Also:</h5>
1775    * <ul>
1776    *    <li class='jf'>{@link RestContext#REST_staticFiles}
1777    * </ul>
1778    *
1779    * @param baseClass
1780    *    Overrides the default class to use for retrieving the classpath resource.
1781    *    <br>If <jk>null<jk>, uses the REST resource class.
1782    * @param path
1783    *    The mapped URI path.
1784    *    <br>Leading and trailing slashes are trimmed.
1785    * @param location
1786    *    The location relative to the resource class.
1787    *    <br>Leading and trailing slashes are trimmed.
1788    * @return This object (for method chaining).
1789    */
1790   public RestContextBuilder staticFiles(Class<?> baseClass, String path, String location) {
1791      return staticFiles(new StaticFileMapping(baseClass, path, location, null));
1792   }
1793
1794   /**
1795    * Configuration property:  Supported accept media types.
1796    *
1797    * <p>
1798    * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource.
1799    *
1800    * <h5 class='section'>See Also:</h5>
1801    * <ul>
1802    *    <li class='jf'>{@link RestContext#REST_produces}
1803    * </ul>
1804    *
1805    * @param append
1806    *    If <jk>true</jk>, append to the existing list, otherwise overwrite the previous value.
1807    * @param values The values to add to this setting.
1808    * @return This object (for method chaining).
1809    */
1810   public RestContextBuilder produces(boolean append, String...values) {
1811      return set(append, REST_produces, values);
1812   }
1813
1814   /**
1815    * Configuration property:  Supported accept media types.
1816    *
1817    * <p>
1818    * Same as {@link #produces(boolean, String...)} except input is {@link MediaType} instances.
1819    *
1820    * <h5 class='section'>See Also:</h5>
1821    * <ul>
1822    *    <li class='jf'>{@link RestContext#REST_produces}
1823    * </ul>
1824    *
1825    * @param append
1826    *    If <jk>true</jk>, append to the existing list, otherwise overwrite the previous value.
1827    * @param values The values to add to this setting.
1828    * @return This object (for method chaining).
1829    */
1830   public RestContextBuilder produces(boolean append, MediaType...values) {
1831      return set(append, REST_produces, values);
1832   }
1833
1834   /**
1835    * Configuration property:  Supported content media types.
1836    *
1837    * <p>
1838    * Overrides the media types inferred from the parsers that identify what media types can be consumed by the resource.
1839    *
1840    * <h5 class='section'>See Also:</h5>
1841    * <ul>
1842    *    <li class='jf'>{@link RestContext#REST_consumes}
1843    * </ul>
1844    *
1845    * @param append
1846    *    If <jk>true</jk>, append to the existing list, otherwise overwrite the previous value.
1847    * @param values The values to add to this setting.
1848    * @return This object (for method chaining).
1849    */
1850   public RestContextBuilder consumes(boolean append, String...values) {
1851      return set(append, REST_consumes, values);
1852   }
1853
1854   /**
1855    * Configuration property:  Supported content media types.
1856    *
1857    * <p>
1858    * Same as {@link #consumes(boolean, String...)} except input is {@link MediaType} instances.
1859    *
1860    * <h5 class='section'>See Also:</h5>
1861    * <ul>
1862    *    <li class='jf'>{@link RestContext#REST_consumes}
1863    * </ul>
1864    *
1865    * @param append
1866    *    If <jk>true</jk>, append to the existing list, otherwise overwrite the previous value.
1867    * @param values The values to add to this setting.
1868    * @return This object (for method chaining).
1869    */
1870   public RestContextBuilder consumes(boolean append, MediaType...values) {
1871      return set(append, REST_consumes, values);
1872   }
1873
1874   /**
1875    * Configuration property:  Resource authority path.
1876    *
1877    * <p>
1878    * Overrides the authority path value for this resource and any child resources.
1879    *
1880    * <p>
1881    * This setting is useful if you want to resolve relative URIs to absolute paths and want to explicitly specify the hostname/port.
1882    *
1883    * <h5 class='section'>See Also:</h5>
1884    * <ul>
1885    *    <li class='jf'>{@link RestContext#REST_uriAuthority}
1886    * </ul>
1887    *
1888    * @param value The new value for this setting.
1889    * @return This object (for method chaining).
1890    */
1891   public RestContextBuilder uriAuthority(String value) {
1892      if (! value.isEmpty())
1893         set(REST_uriAuthority, value);
1894      return this;
1895   }
1896
1897   /**
1898    * Configuration property:  Resource context path.
1899    *
1900    * <p>
1901    * Overrides the context path value for this resource and any child resources.
1902    *
1903    * <p>
1904    * This setting is useful if you want to use <js>"context:/child/path"</js> URLs in child resource POJOs but
1905    * the context path is not actually specified on the servlet container.
1906    *
1907    * <h5 class='section'>See Also:</h5>
1908    * <ul>
1909    *    <li class='jf'>{@link RestContext#REST_uriContext}
1910    * </ul>
1911    *
1912    * @param value The new value for this setting.
1913    * @return This object (for method chaining).
1914    */
1915   public RestContextBuilder uriContext(String value) {
1916      if (! value.isEmpty())
1917         set(REST_uriContext, value);
1918      return this;
1919   }
1920
1921   /**
1922    * Configuration property:  URI resolution relativity.
1923    *
1924    * <p>
1925    * Specifies how relative URIs should be interpreted by serializers.
1926    *
1927    * <p>
1928    * See {@link UriResolution} for possible values.
1929    *
1930    * <h5 class='section'>See Also:</h5>
1931    * <ul>
1932    *    <li class='jf'>{@link RestContext#REST_uriRelativity}
1933    * </ul>
1934    *
1935    * @param value The new value for this setting.
1936    * @return This object (for method chaining).
1937    */
1938   public RestContextBuilder uriRelativity(String value) {
1939      if (! value.isEmpty())
1940         set(REST_uriRelativity, value);
1941      return this;
1942   }
1943
1944   /**
1945    * Configuration property:  URI resolution.
1946    *
1947    * <p>
1948    * Specifies how relative URIs should be interpreted by serializers.
1949    *
1950    * <p>
1951    * See {@link UriResolution} for possible values.
1952    *
1953    * <h5 class='section'>See Also:</h5>
1954    * <ul>
1955    *    <li class='jf'>{@link RestContext#REST_uriResolution}
1956    * </ul>
1957    *
1958    * @param value The new value for this setting.
1959    * @return This object (for method chaining).
1960    */
1961   public RestContextBuilder uriResolution(String value) {
1962      if (! value.isEmpty())
1963         set(REST_uriResolution, value);
1964      return this;
1965   }
1966
1967   /**
1968    * Configuration property:  Use classpath resource caching.
1969    *
1970    * <p>
1971    * When enabled, resources retrieved via {@link RestContext#getClasspathResource(String, Locale)} (and related
1972    * methods) will be cached in memory to speed subsequent lookups.
1973    *
1974    * <h5 class='section'>See Also:</h5>
1975    * <ul>
1976    *    <li class='jf'>{@link RestContext#REST_useClasspathResourceCaching}
1977    * </ul>
1978    *
1979    * @param value
1980    *    The new value for this setting.
1981    *    <br>The default is <jk>true</jk>.
1982    * @return This object (for method chaining).
1983    */
1984   public RestContextBuilder useClasspathResourceCaching(boolean value) {
1985      return set(REST_useClasspathResourceCaching, value);
1986   }
1987
1988   /**
1989    * Configuration property:  Use stack trace hashes.
1990    *
1991    * <p>
1992    * When enabled, the number of times an exception has occurred will be determined based on stack trace hashsums,
1993    * made available through the {@link RestException#getOccurrence()} method.
1994    *
1995    * <h5 class='section'>See Also:</h5>
1996    * <ul>
1997    *    <li class='jf'>{@link RestContext#REST_useStackTraceHashes}
1998    * </ul>
1999    *
2000    * @param value
2001    *    The new value for this setting.
2002    *    <br>The default is <jk>true</jk>.
2003    * @return This object (for method chaining).
2004    */
2005   public RestContextBuilder useStackTraceHashes(boolean value) {
2006      return set(REST_useStackTraceHashes, value);
2007   }
2008
2009   /**
2010    * Configuration property:  HTML Widgets.
2011    *
2012    * <p>
2013    * Defines widgets that can be used in conjunction with string variables of the form <js>"$W{name}"</js>to quickly
2014    * generate arbitrary replacement text.
2015    *
2016    * <h5 class='section'>See Also:</h5>
2017    * <ul>
2018    *    <li class='jf'>{@link RestContext#REST_widgets}
2019    * </ul>
2020    *
2021    * @param values The values to add to this setting.
2022    * @return This object (for method chaining).
2023    */
2024   @SuppressWarnings("unchecked")
2025   public RestContextBuilder widgets(Class<? extends Widget>...values) {
2026      return addTo(REST_widgets, values);
2027   }
2028
2029   /**
2030    * Configuration property:  HTML Widgets.
2031    *
2032    * <p>
2033    * Same as {@link #widgets(Class...)} except input is pre-constructed instances.
2034    *
2035    * <h5 class='section'>See Also:</h5>
2036    * <ul>
2037    *    <li class='jf'>{@link RestContext#REST_widgets}
2038    * </ul>
2039    *
2040    * @param values The values to add to this setting.
2041    * @return This object (for method chaining).
2042    */
2043   public RestContextBuilder widgets(Widget...values) {
2044      return addTo(REST_widgets, values);
2045   }
2046
2047   /**
2048    * Configuration property:  HTML Widgets.
2049    *
2050    * <p>
2051    * Same as {@link #widgets(Widget...)} except allows you to overwrite the previous value.
2052    *
2053    * <h5 class='section'>See Also:</h5>
2054    * <ul>
2055    *    <li class='jf'>{@link RestContext#REST_widgets}
2056    * </ul>
2057    *
2058    * @param append
2059    *    If <jk>true</jk>, appends to the existing list of widgets.
2060    *    <br>Otherwise, replaces the previous list.
2061    * @param values The values to add to this setting.
2062    * @return This object (for method chaining).
2063    */
2064   public RestContextBuilder widgets(boolean append, Widget...values) {
2065      return set(append, REST_widgets, values);
2066   }
2067
2068   @Override /* BeanContextBuilder */
2069   public RestContextBuilder beanClassVisibility(Visibility value) {
2070      super.beanClassVisibility(value);
2071      return this;
2072   }
2073
2074   @Override /* BeanContextBuilder */
2075   public RestContextBuilder beanConstructorVisibility(Visibility value) {
2076      super.beanConstructorVisibility(value);
2077      return this;
2078   }
2079
2080   @Override /* BeanContextBuilder */
2081   public RestContextBuilder beanDictionary(boolean append, Object...values) {
2082      super.beanDictionary(append, values);
2083      return this;
2084   }
2085
2086   @Override /* BeanContextBuilder */
2087   public RestContextBuilder beanDictionary(Class<?>...values) {
2088      super.beanDictionary(values);
2089      return this;
2090   }
2091
2092   @Override /* BeanContextBuilder */
2093   public RestContextBuilder beanDictionary(Object...values) {
2094      super.beanDictionary(values);
2095      return this;
2096   }
2097
2098   @Override /* BeanContextBuilder */
2099   public RestContextBuilder beanDictionaryRemove(Object...values) {
2100      super.beanDictionaryRemove(values);
2101      return this;
2102   }
2103
2104   @Override /* BeanContextBuilder */
2105   public RestContextBuilder beanFieldVisibility(Visibility value) {
2106      super.beanFieldVisibility(value);
2107      return this;
2108   }
2109
2110   @Override /* BeanContextBuilder */
2111   public RestContextBuilder beanFilters(boolean append, Object...values) {
2112      super.beanFilters(append, values);
2113      return this;
2114   }
2115
2116   @Override /* BeanContextBuilder */
2117   public RestContextBuilder beanFilters(Class<?>...values) {
2118      super.beanFilters(values);
2119      return this;
2120   }
2121
2122   @Override /* BeanContextBuilder */
2123   public RestContextBuilder beanFilters(Object...values) {
2124      super.beanFilters(values);
2125      return this;
2126   }
2127
2128   @Override /* BeanContextBuilder */
2129   public RestContextBuilder beanFiltersRemove(Object...values) {
2130      super.beanFiltersRemove(values);
2131      return this;
2132   }
2133
2134   @Override /* BeanContextBuilder */
2135   public RestContextBuilder beanMapPutReturnsOldValue(boolean value) {
2136      super.beanMapPutReturnsOldValue(value);
2137      return this;
2138   }
2139
2140   @Override /* BeanContextBuilder */
2141   public RestContextBuilder beanMapPutReturnsOldValue() {
2142      super.beanMapPutReturnsOldValue();
2143      return this;
2144   }
2145
2146   @Override /* BeanContextBuilder */
2147   public RestContextBuilder beanMethodVisibility(Visibility value) {
2148      super.beanMethodVisibility(value);
2149      return this;
2150   }
2151
2152   @Override /* BeanContextBuilder */
2153   public RestContextBuilder beansRequireDefaultConstructor(boolean value) {
2154      super.beansRequireDefaultConstructor(value);
2155      return this;
2156   }
2157
2158   @Override /* BeanContextBuilder */
2159   public RestContextBuilder beansRequireDefaultConstructor() {
2160      super.beansRequireDefaultConstructor();
2161      return this;
2162   }
2163
2164   @Override /* BeanContextBuilder */
2165   public RestContextBuilder beansRequireSerializable(boolean value) {
2166      super.beansRequireSerializable(value);
2167      return this;
2168   }
2169
2170   @Override /* BeanContextBuilder */
2171   public RestContextBuilder beansRequireSerializable() {
2172      super.beansRequireSerializable();
2173      return this;
2174   }
2175
2176   @Override /* BeanContextBuilder */
2177   public RestContextBuilder beansRequireSettersForGetters(boolean value) {
2178      super.beansRequireSettersForGetters(value);
2179      return this;
2180   }
2181
2182   @Override /* BeanContextBuilder */
2183   public RestContextBuilder beansRequireSettersForGetters() {
2184      super.beansRequireSettersForGetters();
2185      return this;
2186   }
2187
2188   @Override /* BeanContextBuilder */
2189   public RestContextBuilder beansRequireSomeProperties(boolean value) {
2190      super.beansRequireSomeProperties(value);
2191      return this;
2192   }
2193
2194   @Override /* BeanContextBuilder */
2195   public RestContextBuilder beanTypePropertyName(String value) {
2196      super.beanTypePropertyName(value);
2197      return this;
2198   }
2199
2200   @Override /* BeanContextBuilder */
2201   public RestContextBuilder debug() {
2202      super.debug();
2203      return this;
2204   }
2205
2206   @Override /* BeanContextBuilder */
2207   public <T> RestContextBuilder example(Class<T> c, T o) {
2208      super.example(c, o);
2209      return this;
2210   }
2211
2212   @Override /* BeanContextBuilder */
2213   public RestContextBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
2214      super.ignoreInvocationExceptionsOnGetters(value);
2215      return this;
2216   }
2217
2218   @Override /* BeanContextBuilder */
2219   public RestContextBuilder ignoreInvocationExceptionsOnGetters() {
2220      super.ignoreInvocationExceptionsOnGetters();
2221      return this;
2222   }
2223
2224   @Override /* BeanContextBuilder */
2225   public RestContextBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
2226      super.ignoreInvocationExceptionsOnSetters(value);
2227      return this;
2228   }
2229
2230   @Override /* BeanContextBuilder */
2231   public RestContextBuilder ignoreInvocationExceptionsOnSetters() {
2232      super.ignoreInvocationExceptionsOnSetters();
2233      return this;
2234   }
2235
2236   @Override /* BeanContextBuilder */
2237   public RestContextBuilder ignorePropertiesWithoutSetters(boolean value) {
2238      super.ignorePropertiesWithoutSetters(value);
2239      return this;
2240   }
2241
2242   @Override /* BeanContextBuilder */
2243   public RestContextBuilder ignoreUnknownBeanProperties(boolean value) {
2244      super.ignoreUnknownBeanProperties(value);
2245      return this;
2246   }
2247
2248   @Override /* BeanContextBuilder */
2249   public RestContextBuilder ignoreUnknownBeanProperties() {
2250      super.ignoreUnknownBeanProperties();
2251      return this;
2252   }
2253
2254   @Override /* BeanContextBuilder */
2255   public RestContextBuilder ignoreUnknownNullBeanProperties(boolean value) {
2256      super.ignoreUnknownNullBeanProperties(value);
2257      return this;
2258   }
2259
2260   @Override /* BeanContextBuilder */
2261   public <T> RestContextBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
2262      super.implClass(interfaceClass, implClass);
2263      return this;
2264   }
2265
2266   @Override /* BeanContextBuilder */
2267   public RestContextBuilder implClasses(Map<String,Class<?>> values) {
2268      super.implClasses(values);
2269      return this;
2270   }
2271
2272   @Override /* BeanContextBuilder */
2273   public RestContextBuilder locale(Locale value) {
2274      super.locale(value);
2275      return this;
2276   }
2277
2278   @Override /* BeanContextBuilder */
2279   public RestContextBuilder mediaType(MediaType value) {
2280      super.mediaType(value);
2281      return this;
2282   }
2283
2284   @Override /* BeanContextBuilder */
2285   public RestContextBuilder notBeanClasses(boolean append, Object...values) {
2286      super.notBeanClasses(append, values);
2287      return this;
2288   }
2289
2290   @Override /* BeanContextBuilder */
2291   public RestContextBuilder notBeanClasses(Class<?>...values) {
2292      super.notBeanClasses(values);
2293      return this;
2294   }
2295
2296   @Override /* BeanContextBuilder */
2297   public RestContextBuilder notBeanClasses(Object...values) {
2298      super.notBeanClasses(values);
2299      return this;
2300   }
2301
2302   @Override /* BeanContextBuilder */
2303   public RestContextBuilder notBeanClassesRemove(Object...values) {
2304      super.notBeanClassesRemove(values);
2305      return this;
2306   }
2307
2308   @Override /* BeanContextBuilder */
2309   public RestContextBuilder notBeanPackages(boolean append, Object...values) {
2310      super.notBeanPackages(append, values);
2311      return this;
2312   }
2313
2314   @Override /* BeanContextBuilder */
2315   public RestContextBuilder notBeanPackages(Object...values) {
2316      super.notBeanPackages(values);
2317      return this;
2318   }
2319
2320   @Override /* BeanContextBuilder */
2321   public RestContextBuilder notBeanPackages(String...values) {
2322      super.notBeanPackages(values);
2323      return this;
2324   }
2325
2326   @Override /* BeanContextBuilder */
2327   public RestContextBuilder notBeanPackagesRemove(Object...values) {
2328      super.notBeanPackagesRemove(values);
2329      return this;
2330   }
2331
2332   @Override /* BeanContextBuilder */
2333   public RestContextBuilder pojoSwaps(boolean append, Object...values) {
2334      super.pojoSwaps(append, values);
2335      return this;
2336   }
2337
2338   @Override /* BeanContextBuilder */
2339   public RestContextBuilder pojoSwaps(Class<?>...values) {
2340      super.pojoSwaps(values);
2341      return this;
2342   }
2343
2344   @Override /* BeanContextBuilder */
2345   public RestContextBuilder pojoSwaps(Object...values) {
2346      super.pojoSwaps(values);
2347      return this;
2348   }
2349
2350   @Override /* BeanContextBuilder */
2351   public RestContextBuilder pojoSwapsRemove(Object...values) {
2352      super.pojoSwapsRemove(values);
2353      return this;
2354   }
2355
2356   @Override /* BeanContextBuilder */
2357   public RestContextBuilder sortProperties(boolean value) {
2358      super.sortProperties(value);
2359      return this;
2360   }
2361
2362   @Override /* BeanContextBuilder */
2363   public RestContextBuilder sortProperties() {
2364      super.sortProperties();
2365      return this;
2366   }
2367
2368   @Override /* BeanContextBuilder */
2369   public RestContextBuilder timeZone(TimeZone value) {
2370      super.timeZone(value);
2371      return this;
2372   }
2373
2374   @Override /* BeanContextBuilder */
2375   public RestContextBuilder useEnumNames() {
2376      super.useEnumNames();
2377      return this;
2378   }
2379
2380   @Override /* BeanContextBuilder */
2381   public RestContextBuilder useInterfaceProxies(boolean value) {
2382      super.useInterfaceProxies(value);
2383      return this;
2384   }
2385
2386   @Override /* BeanContextBuilder */
2387   public RestContextBuilder useJavaBeanIntrospector(boolean value) {
2388      super.useJavaBeanIntrospector(value);
2389      return this;
2390   }
2391
2392   @Override /* BeanContextBuilder */
2393   public RestContextBuilder useJavaBeanIntrospector() {
2394      super.useJavaBeanIntrospector();
2395      return this;
2396   }
2397
2398   @Override /* ContextBuilder */
2399   public RestContextBuilder set(String name, Object value) {
2400      super.set(name, value);
2401      this.properties.put(name, value);
2402      return this;
2403   }
2404
2405   @Override /* ContextBuilder */
2406   public RestContextBuilder set(boolean append, String name, Object value) {
2407      super.set(append, name, value);
2408      return this;
2409   }
2410
2411   @Override /* ContextBuilder */
2412   public RestContextBuilder set(Map<String,Object> properties) {
2413      super.set(properties);
2414      this.properties.clear();
2415      this.properties.putAll(properties);
2416      return this;
2417   }
2418
2419   @Override /* ContextBuilder */
2420   public RestContextBuilder add(Map<String,Object> properties) {
2421      super.add(properties);
2422      return this;
2423   }
2424
2425   @Override /* ContextBuilder */
2426   public RestContextBuilder addTo(String name, Object value) {
2427      super.addTo(name, value);
2428      return this;
2429   }
2430
2431   @Override /* ContextBuilder */
2432   public RestContextBuilder addTo(String name, String key, Object value) {
2433      super.addTo(name, key, value);
2434      return this;
2435   }
2436
2437   @Override /* ContextBuilder */
2438   public RestContextBuilder removeFrom(String name, Object value) {
2439      super.removeFrom(name, value);
2440      return this;
2441   }
2442
2443   @Override /* ContextBuilder */
2444   public RestContextBuilder apply(PropertyStore copyFrom) {
2445      super.apply(copyFrom);
2446      return this;
2447   }
2448
2449
2450   //----------------------------------------------------------------------------------------------------
2451   // Methods inherited from ServletConfig
2452   //----------------------------------------------------------------------------------------------------
2453
2454   @Override /* ServletConfig */
2455   public String getInitParameter(String name) {
2456      return inner.getInitParameter(name);
2457   }
2458
2459   @Override /* ServletConfig */
2460   public Enumeration<String> getInitParameterNames() {
2461      return inner.getInitParameterNames();
2462   }
2463
2464   @Override /* ServletConfig */
2465   public ServletContext getServletContext() {
2466      return inner.getServletContext();
2467   }
2468
2469   @Override /* ServletConfig */
2470   public String getServletName() {
2471      return inner.getServletName();
2472   }
2473
2474   /**
2475    * @deprecated Unused.
2476    */
2477   @SuppressWarnings("javadoc")
2478   @Deprecated
2479   public RestContextBuilder(ServletConfig config, Class<?> resourceClass) throws ServletException {
2480      this(config, resourceClass, null);
2481   }
2482
2483   /**
2484    * @deprecated Use {@link #uriContext(String)}.
2485    */
2486   @SuppressWarnings("javadoc")
2487   @Deprecated
2488   public RestContextBuilder contextPath(String value) {
2489      return uriContext(value);
2490   }
2491
2492   /**
2493    * @deprecated Use {@link #paramResolvers(RestMethodParam...)}.
2494    */
2495   @SuppressWarnings("javadoc")
2496   @Deprecated
2497   public RestContextBuilder paramResolvers(RestParam...values) {
2498      return this;
2499   }
2500}