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 javax.servlet.http.HttpServletResponse.*;
016import static org.apache.juneau.internal.ClassUtils.*;
017import static org.apache.juneau.internal.CollectionUtils.*;
018import static org.apache.juneau.internal.IOUtils.*;
019import static org.apache.juneau.internal.StringUtils.*;
020
021import java.io.*;
022import java.lang.annotation.*;
023import java.lang.reflect.*;
024import java.lang.reflect.Method;
025import java.nio.charset.*;
026import java.util.*;
027import java.util.concurrent.*;
028import java.util.concurrent.atomic.*;
029
030import javax.activation.*;
031import javax.servlet.*;
032import javax.servlet.http.*;
033
034import org.apache.juneau.*;
035import org.apache.juneau.config.*;
036import org.apache.juneau.encoders.*;
037import org.apache.juneau.html.*;
038import org.apache.juneau.http.*;
039import org.apache.juneau.httppart.*;
040import org.apache.juneau.internal.*;
041import org.apache.juneau.json.*;
042import org.apache.juneau.msgpack.*;
043import org.apache.juneau.parser.*;
044import org.apache.juneau.plaintext.*;
045import org.apache.juneau.rest.annotation.*;
046import org.apache.juneau.rest.converters.*;
047import org.apache.juneau.rest.response.*;
048import org.apache.juneau.rest.vars.*;
049import org.apache.juneau.rest.widget.*;
050import org.apache.juneau.serializer.*;
051import org.apache.juneau.soap.*;
052import org.apache.juneau.svl.*;
053import org.apache.juneau.uon.*;
054import org.apache.juneau.urlencoding.*;
055import org.apache.juneau.utils.*;
056import org.apache.juneau.xml.*;
057
058/**
059 * Contains all the configuration on a REST resource and the entry points for handling REST calls.
060 * 
061 * <h5 class='section'>See Also:</h5>
062 * <ul>
063 *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.RestContext">Overview &gt; juneau-rest-server &gt; RestContext</a>
064 * </ul>
065 */
066public final class RestContext extends BeanContext {
067   
068   //-------------------------------------------------------------------------------------------------------------------
069   // Configurable properties
070   //-------------------------------------------------------------------------------------------------------------------
071
072   private static final String PREFIX = "RestContext.";
073   
074   /**
075    * Configuration property:  Allow body URL parameter.
076    * 
077    * <h5 class='section'>Property:</h5>
078    * <ul>
079    *    <li><b>Name:</b>  <js>"RestContext.allowBodyParam.b"</js>
080    *    <li><b>Data type:</b>  <code>Boolean</code>
081    *    <li><b>Default:</b>  <jk>true</jk>
082    *    <li><b>Session-overridable:</b>  <jk>false</jk>
083    *    <li><b>Annotations:</b>  
084    *       <ul>
085    *          <li class='ja'>{@link RestResource#allowBodyParam()}
086    *       </ul>
087    *    <li><b>Methods:</b>  
088    *       <ul>
089    *          <li class='jm'>{@link RestContextBuilder#allowBodyParam(boolean)}
090    *       </ul>
091    * </ul>
092    * 
093    * <h5 class='section'>Description:</h5>
094    * <p>
095    * When enabled, the HTTP body content on PUT and POST requests can be passed in as text using the <js>"body"</js>
096    * URL parameter.
097    * <br>
098    * For example: 
099    * <p class='bcode'>
100    *  ?body=(name='John%20Smith',age=45)
101    * </p>
102    * 
103    * <h5 class='section'>Example:</h5>
104    * <p class='bcode'>
105    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
106    *    <ja>@RestResource</ja>(allowBodyParam=<js>"$C{REST/allowBodyParam,false}"</js>)
107    *    <jk>public class</jk> MyResource {
108    * 
109    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
110    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
111    *          
112    *          <jc>// Using method on builder.</jc>
113    *          builder.allowBodyParam(<jk>false</jk>);
114    * 
115    *          <jc>// Same, but using property.</jc>
116    *          builder.set(<jsf>REST_allowBodyParam</jsf>, <jk>false</jk>);
117    *       }
118    * 
119    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
120    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
121    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
122    *          builder.allowBodyParam(<jk>false</jk>);
123    *       }
124    *    }
125    * </p>
126    * 
127    * <h5 class='section'>Notes:</h5>
128    * <ul class='spaced-list'>
129    *    <li>
130    *       <js>'body'</js> parameter name is case-insensitive.
131    *    <li>
132    *       Useful for debugging PUT and POST methods using only a browser.
133    * </ul>
134    */
135   public static final String REST_allowBodyParam = PREFIX + "allowBodyParam.b";
136   
137   /**
138    * Configuration property:  Allowed method parameters.
139    * 
140    * <h5 class='section'>Property:</h5>
141    * <ul>
142    *    <li><b>Name:</b>  <js>"RestContext.allowedMethodParams.s"</js>
143    *    <li><b>Data type:</b>  <code>String</code>
144    *    <li><b>Default:</b>  <js>"HEAD,OPTIONS"</js>
145    *    <li><b>Session-overridable:</b>  <jk>false</jk>
146    *    <li><b>Annotations:</b>  
147    *       <ul>
148    *          <li class='ja'>{@link RestResource#allowedMethodParams()}
149    *       </ul>
150    *    <li><b>Methods:</b>  
151    *       <ul>
152    *          <li class='jm'>{@link RestContextBuilder#allowedMethodParams(String...)}
153    *       </ul>
154    * </ul>
155    * 
156    * <h5 class='section'>Description:</h5>
157    * <p>
158    * When specified, the HTTP method can be overridden by passing in a <js>"method"</js> URL parameter on a regular
159    * GET request.
160    * <br>
161    * For example: 
162    * <p class='bcode'>
163    *  ?method=OPTIONS
164    * </p>
165    * 
166    * <h5 class='section'>Example:</h5>
167    * <p class='bcode'>
168    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
169    *    <ja>@RestResource</ja>(allowMethodParams=<js>"$C{REST/allowMethodParams,HEAD\,OPTIONS\,PUT}"</js>)
170    *    <jk>public class</jk> MyResource {
171    * 
172    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
173    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
174    *          
175    *          <jc>// Using method on builder.</jc>
176    *          builder.allowMethodParams(<js>"HEAD,OPTIONS,PUT"</js>);
177    * 
178    *          <jc>// Same, but using property.</jc>
179    *          builder.set(<jsf>REST_allowMethodParams</jsf>, <js>"HEAD,OPTIONS,PUT"</js>);
180    *       }
181    * 
182    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
183    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
184    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
185    *          builder.allowMethodParams(<js>"HEAD"</js>, <js>"OPTIONS"</js>, <js>"PUT"</js>);
186    *       }
187    *    }
188    * </p>
189    * 
190    * <h5 class='section'>Notes:</h5>
191    * <ul class='spaced-list'>
192    *    <li>
193    *       Format is a comma-delimited list of HTTP method names that can be passed in as a method parameter.
194    *    <li>
195    *       <js>'method'</js> parameter name is case-insensitive.
196    *    <li>
197    *       Use <js>"*"</js> to represent all methods.
198    * </ul>
199    * 
200    * <p>
201    * Note that per the <a class="doclink"
202    * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">HTTP specification</a>, special care should
203    * be taken when allowing non-safe (POST, PUT, DELETE) methods to be invoked through GET requests.
204    */
205   public static final String REST_allowedMethodParams = PREFIX + "allowedMethodParams.s";
206
207   /**
208    * Configuration property:  Allow header URL parameters.
209    * 
210    * <h5 class='section'>Property:</h5>
211    * <ul>
212    *    <li><b>Name:</b>  <js>"RestContext.allowHeaderParams.b"</js>
213    *    <li><b>Data type:</b>  <code>Boolean</code>
214    *    <li><b>Default:</b>  <jk>true</jk>
215    *    <li><b>Session-overridable:</b>  <jk>false</jk>
216    *    <li><b>Annotations:</b>  
217    *       <ul>
218    *          <li class='ja'>{@link RestResource#allowHeaderParams()}
219    *       </ul>
220    *    <li><b>Methods:</b>  
221    *       <ul>
222    *          <li class='jm'>{@link RestContextBuilder#allowHeaderParams(boolean)}
223    *       </ul>
224    * </ul>
225    * 
226    * <h5 class='section'>Description:</h5>
227    * <p>
228    * When enabled, headers such as <js>"Accept"</js> and <js>"Content-Type"</js> to be passed in as URL query
229    * parameters.
230    * <br>
231    * For example: 
232    * <p class='bcode'>
233    *  ?Accept=text/json&amp;Content-Type=text/json
234    * </p>
235    * 
236    * <h5 class='section'>Example:</h5>
237    * <p class='bcode'>
238    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
239    *    <ja>@RestResource</ja>(allowMethodParams=<js>"$C{REST/allowHeaderParams,false}"</js>)
240    *    <jk>public class</jk> MyResource {
241    * 
242    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
243    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
244    *          
245    *          <jc>// Using method on builder.</jc>
246    *          builder.allowHeaderParams(<jk>false</jk>);
247    * 
248    *          <jc>// Same, but using property.</jc>
249    *          builder.set(<jsf>REST_allowHeaderParams</jsf>, <jk>false</jk>);
250    *       }
251    * 
252    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
253    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
254    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
255    *          builder.allowHeaderParams(<jk>false</jk>);
256    *       }
257    *    }
258    * </p>
259    * 
260    * <h5 class='section'>Notes:</h5>
261    * <ul class='spaced-list'>
262    *    <li>
263    *       Header names are case-insensitive.
264    *    <li>
265    *       Useful for debugging REST interface using only a browser.
266    * </ul>
267    */
268   public static final String REST_allowHeaderParams = PREFIX + "allowHeaderParams.b";
269   
270   /**
271    * Configuration property:  REST call handler.
272    * 
273    * <h5 class='section'>Property:</h5>
274    * <ul>
275    *    <li><b>Name:</b>  <js>"RestContext.callHandler.o"</js>
276    *    <li><b>Data type:</b>  {@link RestCallHandler} | <code>Class&lt;? <jk>extends</jk> {@link RestCallHandler}&gt;</code>
277    *    <li><b>Default:</b>  {@link BasicRestCallHandler}
278    *    <li><b>Session-overridable:</b>  <jk>false</jk>
279    *    <li><b>Annotations:</b> 
280    *       <ul>
281    *          <li class='ja'>{@link RestResource#callHandler()} 
282    *       </ul>
283    *    <li><b>Methods:</b> 
284    *       <ul>
285    *          <li class='jm'>{@link RestContextBuilder#callHandler(Class)}
286    *          <li class='jm'>{@link RestContextBuilder#callHandler(RestCallHandler)} 
287    *       </ul>
288    * </ul>
289    * 
290    * <h5 class='section'>Description:</h5>
291    * <p>
292    * This class handles the basic lifecycle of an HTTP REST call.
293    * <br>Subclasses can be used to customize how these HTTP calls are handled.
294    * 
295    * <h5 class='section'>Example:</h5>
296    * <p class='bcode'>
297    *    <jc>// Our customized call handler.</jc>
298    *    <jk>public class</jk> MyRestCallHandler <jk>extends</jk> BasicRestCallHandler {
299    *       
300    *       <jc>// Must provide this constructor!</jc>
301    *       <jk>public</jk> MyRestCallHandler(RestContext context) {
302    *          <jk>super</jk>(context);
303    *       }
304    * 
305    *       <ja>@Override</ja>
306    *       <jk>public</jk> RestRequest createRequest(HttpServletRequest req) <jk>throws</jk> ServletException {
307    *          <jc>// Low-level handling of requests.</jc>
308    *          ...
309    *       }
310    *       
311    *       <ja>@Override</ja>
312    *       <jk>public void</jk> handleResponse(RestRequest req, RestResponse res, Object output) <jk>throws</jk> IOException, RestException {
313    *          <jc>// Low-level handling of responses.</jc>
314    *          ...
315    *       }
316    * 
317    *       <ja>@Override</ja>
318    *       <jk>public void</jk> handleNotFound(int rc, RestRequest req, RestResponse res) <jk>throws</jk> Exception {
319    *          <jc>// Low-level handling of various error conditions.</jc>
320    *          ...
321    *       }
322    *    }
323    * 
324    *    <jc>// Option #1 - Registered via annotation resolving to a config file setting with default value.</jc>
325    *    <ja>@RestResource</ja>(callHandler=MyRestCallHandler.<jk>class</jk>)
326    *    <jk>public class</jk> MyResource {
327    * 
328    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
329    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
330    *          
331    *          <jc>// Using method on builder.</jc>
332    *          builder.callHandler(MyRestCallHandler.<jk>class</jk>);
333    * 
334    *          <jc>// Same, but using property.</jc>
335    *          builder.set(<jsf>REST_callHandler</jsf>, MyRestCallHandler.<jk>class</jk>);
336    *       }
337    * 
338    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
339    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
340    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
341    *          builder.callHandler(MyRestCallHandler.<jk>class</jk>);
342    *       }
343    *    }
344    * </p>
345    * 
346    * <h5 class='section'>Notes:</h5>
347    * <ul class='spaced-list'>
348    *    <li>
349    *       When defined as a class, the implementation must have one of the following constructors:
350    *       <ul>
351    *          <li><code><jk>public</jk> T(RestContext)</code>
352    *          <li><code><jk>public</jk> T()</code>
353    *       </ul>
354    *    <li>
355    *       Inner classes of the REST resource class are allowed.
356    * </ul>
357    */
358   public static final String REST_callHandler = PREFIX + "callHandler.o";
359
360   /**
361    * Configuration property:  Children.
362    * 
363    * <h5 class='section'>Property:</h5>
364    * <ul>
365    *    <li><b>Name:</b>  <js>"RestContext.children.lo"</js>
366    *    <li><b>Data type:</b>  <code>List&lt;Class | Object | {@link RestChild}&gt;</code>
367    *    <li><b>Default:</b>  empty list
368    *    <li><b>Session-overridable:</b>  <jk>false</jk>
369    *    <li><b>Annotations:</b>
370    *       <ul>
371    *          <li class='ja'>{@link RestResource#children()}
372    *       </ul>
373    *    <li><b>Methods:</b>
374    *       <ul>
375    *          <li class='jm'>{@link RestContextBuilder#child(String,Object)}
376    *          <li class='jm'>{@link RestContextBuilder#children(Class...)}
377    *          <li class='jm'>{@link RestContextBuilder#children(Object...)}
378    *       </ul>
379    * </ul>
380    * 
381    * <h5 class='section'>Description:</h5>
382    * <p>
383    * Defines children of this resource.
384    * 
385    * <p>
386    * A REST child resource is simply another servlet or object that is initialized as part of the ascendant resource and has a
387    * servlet path directly under the ascendant resource object path.
388    * <br>The main advantage to defining servlets as REST children is that you do not need to define them in the
389    * <code>web.xml</code> file of the web application.
390    * <br>This can cut down on the number of entries that show up in the <code>web.xml</code> file if you are defining
391    * large numbers of servlets.
392    * 
393    * <p>
394    * Child resources must specify a value for {@link RestResource#path() @RestResource.path()} that identifies the subpath of the child resource
395    * relative to the ascendant path UNLESS you use the {@link RestContextBuilder#child(String, Object)} method to register it.
396    * 
397    * <p>
398    * Child resources can be nested arbitrarily deep using this technique (i.e. children can also have children).
399    * 
400    * <dl>
401    *    <dt>Servlet initialization:</dt>
402    *    <dd>
403    *       <p>
404    *          A child resource will be initialized immediately after the ascendant servlet/resource is initialized.
405    *          <br>The child resource receives the same servlet config as the ascendant servlet/resource.
406    *          <br>This allows configuration information such as servlet initialization parameters to filter to child
407    *          resources.
408    *       </p>
409    *    </dd>
410    *    <dt>Runtime behavior:</dt>
411    *    <dd>
412    *       <p>
413    *          As a rule, methods defined on the <code>HttpServletRequest</code> object will behave as if the child
414    *          servlet were deployed as a top-level resource under the child's servlet path.
415    *          <br>For example, the <code>getServletPath()</code> and <code>getPathInfo()</code> methods on the
416    *          <code>HttpServletRequest</code> object will behave as if the child resource were deployed using the
417    *          child's servlet path.
418    *          <br>Therefore, the runtime behavior should be equivalent to deploying the child servlet in the
419    *          <code>web.xml</code> file of the web application.
420    *       </p>
421    *    </dd>
422    * </dl>
423    * 
424    * <h5 class='section'>Example:</h5>
425    * <p class='bcode'>
426    *    <jc>// Our child resource.</jc>
427    *    <ja>@RestResource</ja>(path=<js>"/child"</js>)
428    *    <jk>public class</jk> MyChildResource {...}
429    * 
430    *    <jc>// Option #1 - Registered via annotation.</jc>
431    *    <ja>@RestResource</ja>(children={MyChildResource.<jk>class</jk>})
432    *    <jk>public class</jk> MyResource {
433    * 
434    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
435    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
436    *          
437    *          <jc>// Using method on builder.</jc>
438    *          builder.children(MyChildResource.<jk>class</jk>);
439    * 
440    *          <jc>// Same, but using property.</jc>
441    *          builder.addTo(<jsf>REST_children</jsf>, MyChildResource.<jk>class</jk>));
442    * 
443    *          <jc>// Use a pre-instantiated object instead.</jc>
444    *          builder.child(<js>"/child"</js>, <jk>new</jk> MyChildResource());
445    *       }
446    * 
447    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
448    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
449    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
450    *          builder.children(MyChildResource.<jk>class</jk>);
451    *       }
452    *    }
453    * 
454    * <h5 class='section'>Notes:</h5>
455    * <ul class='spaced-list'>
456    *    <li>
457    *       When defined as classes, instances are resolved using the registered {@link #REST_resourceResolver} which
458    *       by default is {@link BasicRestResourceResolver} which requires the class have one of the following
459    *       constructors:
460    *       <ul>
461    *          <li><code><jk>public</jk> T(RestContextBuilder)</code>
462    *          <li><code><jk>public</jk> T()</code>
463    *       </ul>
464    * </ul>
465    * 
466    * <h5 class='section'>See Also:</h5>
467    * <ul>
468    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Children">Overview &gt; juneau-rest-server &gt; Children</a>
469    * </ul>
470    */
471   public static final String REST_children = PREFIX + "children.lo";
472
473   /**
474    * Configuration property:  Classpath resource finder. 
475    * 
476    * <h5 class='section'>Property:</h5>
477    * <ul>
478    *    <li><b>Name:</b>  <js>"RestContext.classpathResourceFinder.o"</js>
479    *    <li><b>Data type:</b>  {@link ClasspathResourceFinder}
480    *    <li><b>Default:</b>  {@link ClasspathResourceFinderBasic}
481    *    <li><b>Session-overridable:</b>  <jk>false</jk>
482    *    <li><b>Annotations:</b> 
483    *       <ul>
484    *          <li class='ja'>{@link RestResource#classpathResourceFinder()} 
485    *       </ul>
486    *    <li><b>Methods:</b> 
487    *       <ul>
488    *          <li class='jm'>{@link RestContextBuilder#classpathResourceFinder(Class)}
489    *          <li class='jm'>{@link RestContextBuilder#classpathResourceFinder(ClasspathResourceFinder)}
490    *       </ul>
491    * </ul>
492    * 
493    * <h5 class='section'>Description:</h5>
494    * <p>
495    * Used to retrieve localized files from the classpath.
496    * 
497    * <p>
498    * Used by the following methods:
499    * <ul>
500    *    <li class='jc'>{@link RestContext}
501    *    <ul>
502    *       <li class='jm'>{@link #getClasspathResource(String,Locale) getClasspathResource(String,Locale)}
503    *       <li class='jm'>{@link #getClasspathResource(Class,String,Locale) getClasspathResource(Class,String,Locale)}
504    *       <li class='jm'>{@link #getClasspathResource(Class,MediaType,String,Locale) getClasspathResource(Class,MediaType,String,Locale)}
505    *       <li class='jm'>{@link #getClasspathResource(Class,Class,MediaType,String,Locale) getClasspathResource(Class,Class,MediaType,String,Locale)}
506    *       <li class='jm'>{@link #getClasspathResourceAsString(String,Locale) getClasspathResourceAsString(String,Locale)}
507    *       <li class='jm'>{@link #getClasspathResourceAsString(Class,String,Locale) getClasspathResourceAsString(Class,String,Locale)}
508    *       <li class='jm'>{@link #resolveStaticFile(String) resolveStaticFile(String)}
509    *    </ul>
510    *    <li class='jc'>{@link RestRequest}
511    *    <ul>
512    *       <li class='jm'>{@link RestRequest#getClasspathReaderResource(String) getClasspathReaderResource(String)}
513    *       <li class='jm'>{@link RestRequest#getClasspathReaderResource(String,boolean) getClasspathReaderResource(String,boolean)}
514    *       <li class='jm'>{@link RestRequest#getClasspathReaderResource(String,boolean,MediaType) getClasspathReaderResource(String,boolean,MediaType)}
515    *    </ul>
516    * </ul>
517    * 
518    * <p>
519    * It also affects the behavior of the {@link #REST_staticFiles} property.
520    * 
521    * <h5 class='section'>Example:</h5>
522    * <p class='bcode'>
523    *    <jc>// Our customized classpath resource finder.</jc>
524    *    <jk>public class</jk> MyClasspathResourceFinder <jk>extends</jk> ClasspathResourceFinderBasic {
525    *       <ja>@Override</ja> 
526    *       <jk>public</jk> InputStream findResource(Class&lt;?&gt; baseClass, String name, Locale locale) <jk>throws</jk> IOException {
527    *          <jc>// Do your own resolution.</jc>
528    *       }
529    *    }
530    * 
531    *    <jc>// Option #1 - Registered via annotation.</jc>
532    *    <ja>@RestResource</ja>(classpathResourceFinder=MyClasspathResourceFinder.<jk>class</jk>)
533    *    <jk>public class</jk> MyResource {
534    * 
535    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
536    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
537    *          
538    *          <jc>// Using method on builder.</jc>
539    *          builder.classpathResourceFinder(MyClasspathResourceFinder.<jk>class</jk>);
540    * 
541    *          <jc>// Same, but using property.</jc>
542    *          builder.set(<jsf>REST_classpathResourceFinder</jsf>, MyClasspathResourceFinder.<jk>class</jk>));
543    * 
544    *          <jc>// Use a pre-instantiated object instead.</jc>
545    *          builder.classpathResourceFinder(<jk>new</jk> MyClasspathResourceFinder());
546    *       }
547    * 
548    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
549    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
550    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
551    *          builder.classpathResourceFinder(MyClasspathResourceFinder.<jk>class</jk>);
552    *       }
553    *    }
554    * 
555    * <h5 class='section'>Notes:</h5>
556    * <ul class='spaced-list'>
557    *    <li>
558    *       The default value is {@link ClasspathResourceFinderBasic} which provides basic support for finding localized
559    *       resources on the classpath and JVM working directory.
560    *       <br>The {@link ClasspathResourceFinderRecursive} is another option that also recursively searches for resources
561    *       up the class-hierarchy.
562    *       <br>Each of these classes can be extended to provide customized handling of resource retrieval.
563    *    <li>
564    *       When defined as a class, the implementation must have one of the following constructors:
565    *       <ul>
566    *          <li><code><jk>public</jk> T(RestContext)</code>
567    *          <li><code><jk>public</jk> T()</code>
568    *       </ul>
569    *    <li>
570    *       Inner classes of the REST resource class are allowed.
571    * </ul>
572    */
573   public static final String REST_classpathResourceFinder = PREFIX + "classpathResourceFinder.o";
574   
575   /**
576    * Configuration property:  Client version header.
577    * 
578    * <h5 class='section'>Property:</h5>
579    * <ul>
580    *    <li><b>Name:</b>  <js>"RestContext.clientVersionHeader.s"</js>
581    *    <li><b>Data type:</b>  <code>String</code>
582    *    <li><b>Default:</b>  <js>"X-Client-Version"</js>
583    *    <li><b>Session-overridable:</b>  <jk>false</jk>
584    *    <li><b>Annotations:</b> 
585    *       <ul>
586    *          <li class='ja'>{@link RestResource#clientVersionHeader()} 
587    *       </ul>
588    *    <li><b>Methods:</b> 
589    *       <ul>
590    *          <li class='jm'>{@link RestContextBuilder#clientVersionHeader(String)}
591    *       </ul>
592    * </ul>
593    * 
594    * <h5 class='section'>Description:</h5>
595    * <p>
596    * Specifies the name of the header used to denote the client version on HTTP requests.
597    * 
598    * <p>
599    * The client version is used to support backwards compatibility for breaking REST interface changes.
600    * <br>Used in conjunction with {@link RestMethod#clientVersion() @RestMethod.clientVersion()} annotation.
601    * 
602    * <h5 class='section'>Example:</h5>
603    * <p class='bcode'>
604    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
605    *    <ja>@RestResource</ja>(clientVersionHeader=<js>"$C{REST/clientVersionHeader,Client-Version}"</js>)
606    *    <jk>public class</jk> MyResource {
607    * 
608    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
609    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
610    *          
611    *          <jc>// Using method on builder.</jc>
612    *          builder.clientVersionHeader(<js>"Client-Version"</js>);
613    * 
614    *          <jc>// Same, but using property.</jc>
615    *          builder.set(<jsf>REST_clientVersionHeader</jsf>, <js>"Client-Version"</js>);
616    *       }
617    * 
618    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
619    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
620    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
621    *          builder.clientVersionHeader(<js>"Client-Version"</js>);
622    *       }
623    *    }
624    * </p>
625    * <p class='bcode'>
626    *    <jc>// Call this method if Client-Version is at least 2.0.
627    *    // Note that this also matches 2.0.1.</jc>
628    *    <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>)
629    *    <jk>public</jk> Object method1() {
630    *       ...
631    *    }
632    * 
633    *    <jc>// Call this method if Client-Version is at least 1.1, but less than 2.0.</jc>
634    *    <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>)
635    *    <jk>public</jk> Object method2() {
636    *       ...
637    *    }
638    * 
639    *    <jc>// Call this method if Client-Version is less than 1.1.</jc>
640    *    <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[0,1.1)"</js>)
641    *    <jk>public</jk> Object method3() {
642    *       ...
643    *    }
644    * </p>
645    */
646   public static final String REST_clientVersionHeader = PREFIX + "clientVersionHeader.s";
647
648   /**
649    * Configuration property:  Resource context path. 
650    * 
651    * <h5 class='section'>Property:</h5>
652    * <ul>
653    *    <li><b>Name:</b>  <js>"RestContext.contextPath.s"</js>
654    *    <li><b>Data type:</b>  <code>String</code>
655    *    <li><b>Default:</b>  <jk>null</jk>
656    *    <li><b>Session-overridable:</b>  <jk>false</jk>
657    *    <li><b>Annotations:</b> 
658    *       <ul>
659    *          <li class='ja'>{@link RestResource#contextPath()} 
660    *       </ul>
661    *    <li><b>Methods:</b> 
662    *       <ul>
663    *          <li class='jm'>{@link RestContextBuilder#contextPath(String)} 
664    *       </ul>
665    * </ul>
666    * 
667    * <h5 class='section'>Description:</h5>
668    * <p>
669    * Overrides the context path value for this resource and any child resources.
670    * 
671    * <p>
672    * This setting is useful if you want to use <js>"context:/child/path"</js> URLs in child resource POJOs but
673    * the context path is not actually specified on the servlet container.
674    * 
675    * <p>
676    * Affects the following methods:
677    * <ul>
678    *    <li class='jm'>{@link RestRequest#getContextPath()} - Returns the overridden context path for the resource.
679    *    <li class='jm'>{@link RestRequest#getServletPath()} - Includes the overridden context path for the resource.
680    * </ul>
681    * 
682    * <h5 class='section'>Example:</h5>
683    * <p class='bcode'>
684    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
685    *    <ja>@RestResource</ja>(path=<js>"/servlet"</js>, contextPath=<js>"$C{REST/contextPathOverride,/foo}"</js>)
686    *    <jk>public class</jk> MyResource {
687    * 
688    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
689    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
690    *          
691    *          <jc>// Using method on builder.</jc>
692    *          builder.contextPath(<js>"/foo"</js>);
693    * 
694    *          <jc>// Same, but using property.</jc>
695    *          builder.set(<jsf>REST_contextPath</jsf>, <js>"/foo"</js>);
696    *       }
697    * 
698    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
699    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
700    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
701    *          builder.contextPath(<js>"/foo"</js>);
702    *       }
703    *    }
704    * </p>
705    */
706   public static final String REST_contextPath = PREFIX + "contextPath.s";
707   
708   /**
709    * Configuration property:  Class-level response converters.
710    * 
711    * <h5 class='section'>Property:</h5>
712    * <ul>
713    *    <li><b>Name:</b>  <js>"RestContext.converters.lo"</js>
714    *    <li><b>Data type:</b>  <code>List&lt;{@link RestConverter} | Class&lt;? <jk>extends</jk> {@link RestConverter}&gt;&gt;</code>
715    *    <li><b>Default:</b>  empty list
716    *    <li><b>Session-overridable:</b>  <jk>false</jk>
717    *    <li><b>Annotations:</b>  
718    *       <ul>
719    *          <li class='ja'>{@link RestResource#converters()}
720    *          <li class='ja'>{@link RestMethod#converters()}
721    *       </ul>
722    *    <li><b>Methods:</b> 
723    *       <ul>
724    *          <li class='jm'>{@link RestContextBuilder#converters(Class...)}
725    *          <li class='jm'>{@link RestContextBuilder#converters(RestConverter...)}
726    *       </ul>
727    * </ul>
728    * 
729    * <h5 class='section'>Description:</h5>
730    * <p>
731    * Associates one or more {@link RestConverter converters} with a resource class.
732    * <br>These converters get called immediately after execution of the REST method in the same order specified in the
733    * annotation.
734    * <br>The object passed into this converter is the object returned from the Java method or passed into 
735    * the {@link RestResponse#setOutput(Object)} method.
736    * 
737    * <p>
738    * Can be used for performing post-processing on the response object before serialization.
739    * 
740    * <p>
741    *    When multiple converters are specified, they're executed in the order they're specified in the annotation
742    *    (e.g. first the results will be traversed, then the resulting node will be searched/sorted).
743    * 
744    * <h5 class='section'>Example:</h5>
745    * <p class='bcode'>
746    *    <jc>// Our converter.</jc>
747    *    <jk>public class</jk> MyConverter <jk>implements</jk> RestConverter {
748    *       <ja>@Override</ja>
749    *       <jk>public</jk> Object convert(RestRequest req, Object o) {
750    *          <jc>// Do something with object and return another object.</jc>
751    *          <jc>// Or just return the same object for a no-op.</jc>
752    *       }
753    *    }
754    * 
755    *    <jc>// Option #1 - Registered via annotation resolving to a config file setting with default value.</jc>
756    *    <ja>@RestResource</ja>(converters={MyConverter.<jk>class</jk>})
757    *    <jk>public class</jk> MyResource {
758    * 
759    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
760    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
761    *          
762    *          <jc>// Using method on builder.</jc>
763    *          builder.converters(MyConverter.<jk>class</jk>);
764    * 
765    *          <jc>// Same, but using property.</jc>
766    *          builder.set(<jsf>REST_converters</jsf>, MyConverter.<jk>class</jk>);
767    *          
768    *          <jc>// Pass in an instance instead.</jc>
769    *          builder.converters(<jk>new</jk> MyConverter());
770    *       }
771    * 
772    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
773    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
774    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
775    *          builder.converters(MyConverter.<jk>class</jk>);
776    *       }
777    *    }
778    * </p>
779    * 
780    * <h5 class='section'>See Also:</h5>
781    * <ul>
782    *    <li class='jc'>{@link Traversable} - Allows URL additional path info to address individual elements in a POJO tree.
783    *    <li class='jc'>{@link Queryable} - Allows query/view/sort functions to be performed on POJOs.
784    *    <li class='jc'>{@link Introspectable} - Allows Java public methods to be invoked on the returned POJOs.
785    * </ul>
786    * 
787    * <h5 class='section'>See Also:</h5>
788    * <ul>
789    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Converters">Overview &gt; juneau-rest-server &gt; Converters</a>
790    * </ul>
791    * 
792    * <h5 class='section'>Notes:</h5>
793    * <ul class='spaced-list'>
794    *    <li>
795    *       When defined as a class, the implementation must have one of the following constructors:
796    *       <ul>
797    *          <li><code><jk>public</jk> T(BeanContext)</code>
798    *          <li><code><jk>public</jk> T()</code>
799    *       </ul>
800    *    <li>
801    *       Inner classes of the REST resource class are allowed.
802    * </ul>
803    */
804   public static final String REST_converters = PREFIX + "converters.lo";
805
806   /**
807    * Configuration property:  Default character encoding.
808    * 
809    * <h5 class='section'>Property:</h5>
810    * <ul>
811    *    <li><b>Name:</b>  <js>"RestContext.defaultCharset.s"</js>
812    *    <li><b>Data type:</b>  <code>String</code>
813    *    <li><b>Default:</b>  <js>"utf-8"</js>
814    *    <li><b>Session-overridable:</b>  <jk>false</jk>
815    *    <li><b>Annotations:</b>  
816    *       <ul>
817    *          <li class='ja'>{@link RestResource#defaultCharset()}
818    *          <li class='ja'>{@link RestMethod#defaultCharset()}
819    *       </ul>
820    *    <li><b>Methods:</b>  
821    *       <ul>
822    *          <li class='jm'>{@link RestContextBuilder#defaultCharset(String)}
823    *          <li class='jm'>{@link RestContextBuilder#defaultCharset(Charset)}
824    *       </ul>
825    * </ul>
826    * 
827    * <h5 class='section'>Description:</h5>
828    * <p>
829    * The default character encoding for the request and response if not specified on the request.
830    * 
831    * <h5 class='section'>Example:</h5>
832    * <p class='bcode'>
833    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
834    *    <ja>@RestResource</ja>(defaultCharset=<js>"$C{REST/defaultCharset,US-ASCII}"</js>)
835    *    <jk>public class</jk> MyResource {
836    *       
837    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
838    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
839    *          
840    *          <jc>// Using method on builder.</jc>
841    *          builder.defaultCharset(<js>"US-ASCII"</js>);
842    * 
843    *          <jc>// Same, but using property.</jc>
844    *          builder.set(<jsf>REST_defaultCharset</jsf>, <js>"US-ASCII"</js>);
845    *       }
846    * 
847    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
848    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
849    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
850    *          builder.defaultCharset(<js>"US-ASCII"</js>);
851    *       }
852    *       
853    *       <jc>// Override at the method level.</jc>
854    *       <ja>@RestMethod</ja>(defaultCharset=<js>"UTF-16"</js>)
855    *       public Object myMethod() {...}
856    *    }
857    * </p>
858    */
859   public static final String REST_defaultCharset = PREFIX + "defaultCharset.s";
860   
861   /**
862    * Configuration property:  Default request headers.
863    * 
864    * <h5 class='section'>Property:</h5>
865    * <ul>
866    *    <li><b>Name:</b>  <js>"RestContext.defaultRequestHeaders.smo"</js>
867    *    <li><b>Data type:</b>  <code>Map&lt;String,String&gt;</code>
868    *    <li><b>Default:</b>  empty map
869    *    <li><b>Session-overridable:</b>  <jk>false</jk>
870    *    <li><b>Annotations:</b>  
871    *       <ul>
872    *          <li class='ja'>{@link RestResource#defaultRequestHeaders()}
873    *          <li class='ja'>{@link RestMethod#defaultRequestHeaders()} 
874    *       </ul>
875    *    <li><b>Methods:</b>  
876    *       <ul>
877    *          <li class='jm'>{@link RestContextBuilder#defaultRequestHeader(String,Object)}
878    *          <li class='jm'>{@link RestContextBuilder#defaultRequestHeaders(String...)}
879    *       </ul>
880    * </ul>
881    * 
882    * <h5 class='section'>Description:</h5>
883    * <p>
884    * Specifies default values for request headers if they're not passed in through the request.
885    * 
886    * <h5 class='section'>Notes:</h5>
887    * <ul class='spaced-list'>
888    *    <li>  
889    *       Strings are in the format <js>"Header-Name: header-value"</js>.
890    *    <li>
891    *       Affects values returned by {@link RestRequest#getHeader(String)} when the header is not present on the request.
892    *    <li>
893    *       The most useful reason for this annotation is to provide a default <code>Accept</code> header when one is not
894    *       specified so that a particular default {@link Serializer} is picked.
895    * </ul>
896    * 
897    * <h5 class='section'>Example:</h5>
898    * <p class='bcode'>
899    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
900    *    <ja>@RestResource</ja>(defaultRequestHeaders={<js>"Accept: application/json"</js>, <js>"My-Header: $C{REST/myHeaderValue}"</js>})
901    *    <jk>public class</jk> MyResource {
902    * 
903    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
904    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
905    *          
906    *          <jc>// Using method on builder.</jc>
907    *          builder
908    *             .defaultRequestHeader(<js>"Accept"</js>, <js>"application/json"</js>);
909    *             .defaultRequestHeaders(<js>"My-Header: foo"</js>);
910    * 
911    *          <jc>// Same, but using property.</jc>
912    *          builder.addTo(<jsf>REST_defaultRequestHeaders</jsf>, <js>"Accept"</js>, <js>"application/json"</js>);
913    *       }
914    * 
915    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
916    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
917    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
918    *          builder.defaultRequestHeader(<js>"Accept"</js>, <js>"application/json"</js>);
919    *       }
920    *       
921    *       <jc>// Override at the method level.</jc>
922    *       <ja>@RestMethod</ja>(defaultRequestHeaders={<js>"Accept: text/xml"</js>})
923    *       public Object myMethod() {...}
924    *    }
925    * </p>
926    */
927   public static final String REST_defaultRequestHeaders = PREFIX + "defaultRequestHeaders.smo";
928
929   /**
930    * Configuration property:  Default response headers.
931    * 
932    * <h5 class='section'>Property:</h5>
933    * <ul>
934    *    <li><b>Name:</b>  <js>"RestContext.defaultResponseHeaders.omo"</js>
935    *    <li><b>Data type:</b>  <code>Map&lt;String,String&gt;</code>
936    *    <li><b>Default:</b>  empty map
937    *    <li><b>Session-overridable:</b>  <jk>false</jk>
938    *    <li><b>Annotations:</b> 
939    *       <ul>
940    *          <li class='ja'>{@link RestResource#defaultResponseHeaders()} 
941    *       </ul>
942    *    <li><b>Methods:</b>  
943    *       <ul>
944    *          <li class='jm'>{@link RestContextBuilder#defaultResponseHeader(String,Object)}
945    *          <li class='jm'>{@link RestContextBuilder#defaultResponseHeaders(String...)}
946    *       </ul>
947    * </ul>
948    * 
949    * <h5 class='section'>Description:</h5>
950    * <p>
951    * Specifies default values for response headers if they're not set after the Java REST method is called.
952    * 
953    * <h5 class='section'>Notes:</h5>
954    * <ul class='spaced-list'>
955    *    <li>
956    *       Strings are in the format <js>"Header-Name: header-value"</js>.
957    *    <li>
958    *       This is equivalent to calling {@link RestResponse#setHeader(String, String)} programmatically in each of 
959    *       the Java methods.
960    *    <li>  
961    *       The header value will not be set if the header value has already been specified (hence the 'default' in the name).
962    * </ul>
963    * 
964    * <h5 class='section'>Example:</h5>
965    * <p class='bcode'>
966    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
967    *    <ja>@RestResource</ja>(defaultResponseHeaders={<js>"Content-Type: $C{REST/defaultContentType,text/plain}"</js>,<js>"My-Header: $C{REST/myHeaderValue}"</js>})
968    *    <jk>public class</jk> MyResource {
969    * 
970    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
971    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
972    *          
973    *          <jc>// Using method on builder.</jc>
974    *          builder
975    *             .defaultResponseHeader(<js>"Content-Type"</js>, <js>"text/plain"</js>);
976    *             .defaultResponseHeaders(<js>"My-Header: foo"</js>);
977    * 
978    *          <jc>// Same, but using property.</jc>
979    *          builder
980    *             .addTo(<jsf>REST_defaultRequestHeaders</jsf>, <js>"Accept"</js>, <js>"application/json"</js>);
981    *             .addTo(<jsf>REST_defaultRequestHeaders</jsf>, <js>"My-Header"</js>, <js>"foo"</js>);
982    *       }
983    * 
984    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
985    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
986    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
987    *          builder.defaultResponseHeader(<js>"Content-Type"</js>, <js>"text/plain"</js>);
988    *       }
989    *    }
990    * </p>
991    */
992   public static final String REST_defaultResponseHeaders = PREFIX + "defaultResponseHeaders.omo";
993
994   /**
995    * Configuration property:  Compression encoders. 
996    * 
997    * <h5 class='section'>Property:</h5>
998    * <ul>
999    *    <li><b>Name:</b>  <js>"RestContext.encoders.o"</js>
1000    *    <li><b>Data type:</b>  <code>List&lt;{@link Encoder} | Class&lt;? <jk>extends</jk> {@link Encoder}&gt;&gt;</code>
1001    *    <li><b>Default:</b>  empty list
1002    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1003    *    <li><b>Annotations:</b> 
1004    *       <ul>
1005    *          <li class='ja'>{@link RestResource#encoders()} 
1006    *          <li class='ja'>{@link RestMethod#encoders()} 
1007    *       </ul>
1008    *    <li><b>Methods:</b> 
1009    *       <ul>
1010    *          <li class='jm'>{@link RestContextBuilder#encoders(Class...)}
1011    *          <li class='jm'>{@link RestContextBuilder#encoders(Encoder...)}
1012    *       </ul>
1013    * </ul>
1014    * 
1015    * <h5 class='section'>Description:</h5>
1016    * <p>
1017    * These can be used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses.
1018    * 
1019    * <h5 class='section'>Example:</h5>
1020    * <p class='bcode'>
1021    *    <jc>// Option #1 - Registered via annotation.</jc>
1022    *    <ja>@RestResource</ja>(encoders={GzipEncoder.<jk>class</jk>})
1023    *    <jk>public class</jk> MyResource {
1024    * 
1025    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
1026    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1027    *          
1028    *          <jc>// Using method on builder.</jc>
1029    *          builder.encoders(GzipEncoder.<jk>class</jk>);
1030    * 
1031    *          <jc>// Same, but using property.</jc>
1032    *          builder.addTo(<jsf>REST_encoders</jsf>, GzipEncoder.<jk>class</jk>);
1033    *       }
1034    * 
1035    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
1036    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1037    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1038    *          builder.encoders(GzipEncoder.<jk>class</jk>);
1039    *       }
1040    * 
1041    *       <jc>// Override at the method level.</jc>
1042    *       <ja>@RestMethod</ja>(encoders={MySpecialEncoder.<jk>class</jk>}, inherit={<js>"ENCODERS"</js>})
1043    *       public Object myMethod() {...}
1044    *    }
1045    * </p>
1046    * 
1047    * <h5 class='section'>Notes:</h5>
1048    * <ul class='spaced-list'>
1049    *    <li>
1050    *       When defined as a class, the implementation must have one of the following constructors:
1051    *       <ul>
1052    *          <li><code><jk>public</jk> T(BeanContext)</code>
1053    *          <li><code><jk>public</jk> T()</code>
1054    *       </ul>
1055    *    <li>
1056    *       Inner classes of the REST resource class are allowed.
1057    * </ul>
1058    * 
1059    * <h5 class='section'>See Also:</h5>
1060    * <ul>
1061    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Encoders">Overview &gt; juneau-rest-server &gt; Encoders</a>
1062    * </ul>
1063    */
1064   public static final String REST_encoders = PREFIX + "encoders.lo";
1065
1066   /**
1067    * Configuration property:  Class-level guards.
1068    * 
1069    * <h5 class='section'>Property:</h5>
1070    * <ul>
1071    *    <li><b>Name:</b>  <js>"RestContext.guards.lo"</js>
1072    *    <li><b>Data type:</b>  <code>List&lt;{@link RestGuard} | Class&lt;? <jk>extends</jk> {@link RestGuard}&gt;&gt;</code>
1073    *    <li><b>Default:</b>  empty list
1074    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1075    *    <li><b>Annotations:</b>  
1076    *       <ul>
1077    *          <li class='ja'>{@link RestResource#guards()}
1078    *          <li class='ja'>{@link RestMethod#guards()}
1079    *       </ul>
1080    *    <li><b>Methods:</b> 
1081    *       <ul>
1082    *          <li class='jm'>{@link RestContextBuilder#guards(Class...)}
1083    *          <li class='jm'>{@link RestContextBuilder#guards(RestGuard...)}
1084    *       </ul>
1085    * </ul>
1086    * 
1087    * <h5 class='section'>Description:</h5>
1088    * <p>
1089    * Associates one or more {@link RestGuard RestGuards} with all REST methods defined in this class.
1090    * <br>These guards get called immediately before execution of any REST method in this class.
1091    * 
1092    * <p>
1093    * If multiple guards are specified, <b>ALL</b> guards must pass.
1094    * <br>Note that this is different than matchers were only ONE matcher needs to pass.
1095    * 
1096    * <h5 class='section'>Example:</h5>
1097    * <p class='bcode'>
1098    *    <jc>// Define a guard that only lets Billy make a request.</jc>
1099    *    <jk>public</jk> BillyGuard <jk>extends</jk> RestGuard {
1100    *       <ja>@Override</ja>
1101    *       <jk>public boolean</jk> isRequestAllowed(RestRequest req) {
1102    *          <jk>return</jk> req.getUserPrincipal().getName().equals(<js>"Billy"</js>);
1103    *       }
1104    *    }
1105    * 
1106    *    <jc>// Option #1 - Registered via annotation.</jc>
1107    *    <ja>@RestResource</ja>(guards={BillyGuard.<jk>class</jk>})
1108    *    <jk>public class</jk> MyResource {
1109    * 
1110    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
1111    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1112    *          
1113    *          <jc>// Using method on builder.</jc>
1114    *          builder.guards(BillyGuard.<jk>class</jk>);
1115    * 
1116    *          <jc>// Same, but using property.</jc>
1117    *          builder.addTo(<jsf>REST_guards</jsf>, BillyGuard.<jk>class</jk>);
1118    *       }
1119    * 
1120    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
1121    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1122    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1123    *          builder.guards(BillyGuard.<jk>class</jk>);
1124    *       }
1125    * 
1126    *       <jc>// Override at the method level.</jc>
1127    *       <ja>@RestMethod</ja>(guards={SomeOtherGuard.<jk>class</jk>})
1128    *       public Object myMethod() {...}
1129    *    }
1130    * </p>
1131    * 
1132    * <h5 class='section'>Notes:</h5>
1133    * <ul class='spaced-list'>
1134    *    <li>
1135    *       When defined as a class, the implementation must have one of the following constructors:
1136    *       <ul>
1137    *          <li><code><jk>public</jk> T(RestContext)</code>
1138    *          <li><code><jk>public</jk> T()</code>
1139    *       </ul>
1140    *    <li>
1141    *       Inner classes of the REST resource class are allowed.
1142    * </ul>
1143    * 
1144    * <h5 class='section'>See Also:</h5>
1145    * <ul>
1146    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Guards">Overview &gt; juneau-rest-server &gt; Guards</a>
1147    * </ul>
1148    */
1149   public static final String REST_guards = PREFIX + "guards.lo";
1150
1151   /**
1152    * Configuration property:  REST info provider. 
1153    * 
1154    * <h5 class='section'>Property:</h5>
1155    * <ul>
1156    *    <li><b>Name:</b>  <js>"RestContext.infoProvider.o"</js>
1157    *    <li><b>Data type:</b>  <code>{@link RestInfoProvider} | Class&lt;? <jk>extends</jk> {@link RestInfoProvider}&gt;</code>
1158    *    <li><b>Default:</b>  {@link BasicRestInfoProvider}
1159    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1160    *    <li><b>Annotations:</b> 
1161    *       <ul>
1162    *          <li class='ja'>{@link RestResource#infoProvider()} 
1163    *       </ul>
1164    *    <li><b>Methods:</b> 
1165    *       <ul>
1166    *          <li class='jm'>{@link RestContextBuilder#infoProvider(Class)}
1167    *          <li class='jm'>{@link RestContextBuilder#infoProvider(RestInfoProvider)} 
1168    *       </ul>
1169    * </ul>
1170    * 
1171    * <h5 class='section'>Description:</h5>
1172    * <p>
1173    * Class used to retrieve title/description/swagger information about a resource.
1174    * 
1175    * <h5 class='section'>Example:</h5>
1176    * <p class='bcode'>
1177    *    <jc>// Our customized info provider.</jc>
1178    *    <jc>// Extend from the default implementation and selectively override values.</jc>
1179    *    <jk>public class</jk> MyRestInfoProvider <jk>extends</jk> BasicRestInfoProvider {
1180    *       
1181    *       <jc>// Must provide this constructor!</jc>
1182    *       <jk>public</jk> MyRestInfoProvider(RestContext context) {
1183    *          <jk>super</jk>(context);
1184    *       }
1185    * 
1186    *       <ja>@Override</ja>
1187    *       <jk>public</jk> Swagger getSwaggerFromFile(RestRequest req) <jk>throws</jk> RestException {
1188    *          <jc>// Provide our own method of retrieving swagger from file system.</jc>
1189    *       }
1190    * 
1191    *       <ja>@Override</ja>
1192    *       <jk>public</jk> Swagger getSwagger(RestRequest req) <jk>throws</jk> RestException {
1193    *          Swagger s = <jk>super</jk>.getSwagger(req);
1194    *          <jc>// Made inline modifications to generated swagger.</jc>
1195    *          <jk>return</jk> s;
1196    *       }
1197    * 
1198    *       <ja>@Override</ja>
1199    *       <jk>public</jk> String getSiteName(RestRequest req) {
1200    *          <jc>// Override the site name.</jc>
1201    *       }
1202    *    }
1203    * 
1204    *    <jc>// Option #1 - Registered via annotation resolving to a config file setting with default value.</jc>
1205    *    <ja>@RestResource</ja>(infoProvider=MyRestInfoProvider.<jk>class</jk>)
1206    *    <jk>public class</jk> MyResource {
1207    * 
1208    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
1209    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1210    *          
1211    *          <jc>// Using method on builder.</jc>
1212    *          builder.infoProvider(MyRestInfoProvider.<jk>class</jk>);
1213    * 
1214    *          <jc>// Same, but using property.</jc>
1215    *          builder.set(<jsf>REST_infoProvider</jsf>, MyRestInfoProvider.<jk>class</jk>);
1216    *       }
1217    * 
1218    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
1219    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1220    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1221    *          builder.infoProvider(MyRestInfoProvider.<jk>class</jk>);
1222    *       }
1223    *    }
1224    * </p>
1225    * 
1226    * <h5 class='section'>Notes:</h5>
1227    * <ul class='spaced-list'>
1228    *    <li>
1229    *       When defined as a class, the implementation must have one of the following constructors:
1230    *       <ul>
1231    *          <li><code><jk>public</jk> T(RestContext)</code>
1232    *          <li><code><jk>public</jk> T()</code>
1233    *       </ul>
1234    *    <li>
1235    *       Inner classes of the REST resource class are allowed.
1236    * </ul>
1237    */
1238   public static final String REST_infoProvider = PREFIX + "infoProvider.o";
1239   
1240   /**
1241    * Configuration property:  REST logger.
1242    * 
1243    * <h5 class='section'>Property:</h5>
1244    * <ul>
1245    *    <li><b>Name:</b>  <js>"RestContext.logger.o"</js>
1246    *    <li><b>Data type:</b>  <code>{@link RestLogger} | Class&lt;? <jk>extends</jk> {@link RestLogger}&gt;</code>
1247    *    <li><b>Default:</b>  {@link BasicRestLogger}
1248    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1249    *    <li><b>Annotations:</b> 
1250    *       <ul>
1251    *          <li class='ja'>{@link RestResource#logger()} 
1252    *       </ul>
1253    *    <li><b>Methods:</b>  
1254    *       <ul>
1255    *          <li class='jm'>{@link RestContextBuilder#logger(Class)}
1256    *          <li class='jm'>{@link RestContextBuilder#logger(RestLogger)} 
1257    *       </ul>
1258    * </ul>
1259    * 
1260    * <h5 class='section'>Description:</h5>
1261    * <p>
1262    * Specifies the logger to use for logging.
1263    * 
1264    * <p>
1265    * Two implementations are provided by default:
1266    * <ul>
1267    *    <li class='jc'>{@link BasicRestLogger} - Default logging.
1268    *    <li class='jc'>{@link NoOpRestLogger} - Logging disabled.
1269    * </ul>
1270    * 
1271    * <p>
1272    * Loggers are accessible through the following:
1273    * <ul>
1274    *    <li class='jm'>{@link RestContext#getLogger() RestContext.getLogger()}
1275    *    <li class='jm'>{@link RestRequest#getLogger() RestRequest.getLogger()}
1276    * </ul>
1277    * 
1278    * <h5 class='section'>Example:</h5>
1279    * <p class='bcode'>
1280    *    <jc>// Our customized logger.</jc>
1281    *    <jk>public class</jk> MyRestLogger <jk>extends</jk> BasicRestLogger {
1282    *       
1283    *       <ja>@Override</ja>
1284    *       <jk>public void</jk> log(Level level, Throwable cause, String msg, Object...args) {
1285    *          <jc>// Handle logging ourselves.</jc>
1286    *       }
1287    *    }
1288    * 
1289    *    <jc>// Option #1 - Registered via annotation resolving to a config file setting with default value.</jc>
1290    *    <ja>@RestResource</ja>(logger=MyRestLogger.<jk>class</jk>)
1291    *    <jk>public class</jk> MyResource {
1292    * 
1293    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
1294    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1295    *          
1296    *          <jc>// Using method on builder.</jc>
1297    *          builder.logger(MyRestLogger.<jk>class</jk>);
1298    * 
1299    *          <jc>// Same, but using property.</jc>
1300    *          builder.set(<jsf>REST_logger</jsf>, MyRestLogger.<jk>class</jk>);
1301    *       }
1302    * 
1303    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
1304    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1305    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1306    *          builder.logger(MyRestLogger.<jk>class</jk>);
1307    *       }
1308    *    }
1309    * </p>
1310    * 
1311    * <h5 class='section'>See Also:</h5>
1312    * <ul>
1313    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.LoggingAndErrorHandling">Overview &gt; juneau-rest-server &gt; Logging and Error Handling</a>
1314    * </ul>
1315    */
1316   public static final String REST_logger = PREFIX + "logger.o";
1317
1318   /**
1319    * Configuration property:  The maximum allowed input size (in bytes) on HTTP requests.
1320    * 
1321    * <h5 class='section'>Property:</h5>
1322    * <ul>
1323    *    <li><b>Name:</b>  <js>"RestContext.maxInput.s"</js>
1324    *    <li><b>Data type:</b>  <code>String</code>
1325    *    <li><b>Default:</b>  <js>"100M"</js>
1326    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1327    *    <li><b>Annotations:</b>  
1328    *       <ul>
1329    *          <li class='ja'>{@link RestResource#maxInput()}
1330    *          <li class='ja'>{@link RestMethod#maxInput()}
1331    *       </ul>
1332    *    <li><b>Methods:</b>  
1333    *       <ul>
1334    *          <li class='jm'>{@link RestContextBuilder#maxInput(String)}
1335    *       </ul>
1336    * </ul>
1337    * 
1338    * <h5 class='section'>Description:</h5>
1339    * <p>
1340    * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting
1341    * in out-of-memory errors which could affect system stability.
1342    * 
1343    * <h5 class='section'>Example:</h5>
1344    * <p class='bcode'>
1345    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
1346    *    <ja>@RestResource</ja>(maxInput=<js>"$C{REST/maxInput,10M}"</js>)
1347    *    <jk>public class</jk> MyResource {
1348    * 
1349    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
1350    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1351    *          
1352    *          <jc>// Using method on builder.</jc>
1353    *          builder.maxInput(<js>"10M"</js>);
1354    * 
1355    *          <jc>// Same, but using property.</jc>
1356    *          builder.set(<jsf>REST_maxInput</jsf>, <js>"10M"</js>);
1357    *       }
1358    * 
1359    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
1360    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1361    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1362    *          builder.maxInput(<js>"10M"</js>);
1363    *       }
1364    *       
1365    *       <jc>// Override at the method level.</jc>
1366    *       <ja>@RestMethod</ja>(maxInput=<js>"10M"</js>)
1367    *       public Object myMethod() {...}
1368    *    }
1369    * </p>
1370    * 
1371    * <h5 class='section'>Notes:</h5>
1372    * <ul class='spaced-list'>
1373    *    <li>
1374    *       String value that gets resolved to a <jk>long</jk>.
1375    *    <li>
1376    *       Can be suffixed with any of the following representing kilobytes, megabytes, and gigabytes:  
1377    *       <js>'K'</js>, <js>'M'</js>, <js>'G'</js>.
1378    *    <li>
1379    *       A value of <js>"-1"</js> can be used to represent no limit.
1380    * </ul>
1381    */
1382   public static final String REST_maxInput = PREFIX + "maxInput.s";
1383   
1384   /**
1385    * Configuration property:  Messages. 
1386    * 
1387    * <h5 class='section'>Property:</h5>
1388    * <ul>
1389    *    <li><b>Name:</b>  <js>"RestContext.messages.lo"</js>
1390    *    <li><b>Data type:</b>  <code>List&lt;{@link MessageBundleLocation}&gt;</code>
1391    *    <li><b>Default:</b>  <jk>null</jk>
1392    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1393    *    <li><b>Annotations:</b> 
1394    *       <ul>
1395    *          <li class='ja'>{@link RestResource#messages()} 
1396    *       </ul>
1397    *    <li><b>Methods:</b> 
1398    *       <ul>
1399    *          <li class='jm'>{@link RestContextBuilder#messages(String)},
1400    *          <li class='jm'>{@link RestContextBuilder#messages(Class,String)}
1401    *          <li class='jm'>{@link RestContextBuilder#messages(MessageBundleLocation...)} 
1402    *       </ul>
1403    * </ul>
1404    * 
1405    * <h5 class='section'>Description:</h5>
1406    * <p>
1407    * Identifies the location of the resource bundle for this class.
1408    * 
1409    * <p>
1410    * This annotation is used to provide localized messages for the following methods:
1411    * <ul>
1412    *    <li class='jm'>{@link RestRequest#getMessage(String, Object...)}
1413    *    <li class='jm'>{@link RestContext#getMessages() RestContext.getMessages()}
1414    * </ul>
1415    * 
1416    * <p>
1417    * Messages are also available by passing either of the following parameter types into your Java method:
1418    * <ul>
1419    *    <li class='jc'>{@link ResourceBundle} - Basic Java resource bundle.
1420    *    <li class='jc'>{@link MessageBundle} - Extended resource bundle with several convenience methods.
1421    * </ul>
1422    * 
1423    * <p>
1424    * Messages passed into Java methods already have their locale set to that of the incoming request.
1425    * 
1426    * <p>
1427    * The value can be a relative path like <js>"nls/Messages"</js>, indicating to look for the resource bundle
1428    * <js>"com.foo.sample.nls.Messages"</js> if the resource class is in <js>"com.foo.sample"</js>, or it can be an
1429    * absolute path like <js>"com.foo.sample.nls.Messages"</js>
1430    * 
1431    * <h5 class='section'>Examples:</h5>
1432    * <p class='bcode'>
1433    *    <jk>package</jk> org.apache.foo;
1434    * 
1435    *    <jc>// Resolve messages to org/apache/foo/nls/MyMessages.properties</jc>
1436    *    <ja>@RestResource</ja>(messages=<js>"nls/MyMessages"</js>)
1437    *    <jk>public class</jk> MyResource {...}
1438    * 
1439    *       <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/hello/{you}"</js>)
1440    *       <jk>public</jk> Object helloYou(RestRequest req, MessageBundle messages, <ja>@Path</ja>(<js>"name"</js>) String you)) {
1441    *          String s;
1442    * 
1443    *          <jc>// Get it from the RestRequest object.</jc>
1444    *          s = req.getMessage(<js>"HelloMessage"</js>, you);
1445    * 
1446    *          <jc>// Or get it from the method parameter.</jc>
1447    *          s = messages.getString(<js>"HelloMessage"</js>, you);
1448    * 
1449    *          <jc>// Or get the message in a locale different from the request.</jc>
1450    *          s = messages.getString(Locale.<jsf>UK</jsf>, <js>"HelloMessage"</js>, you);
1451    * 
1452    *          <jk>return</jk> s;
1453    *       }
1454    *    }
1455    * </p>
1456    * 
1457    * <h5 class='section'>Notes:</h5>
1458    * <ul class='spaced-list'>
1459    *    <li
1460    *       >Mappings are cumulative from super classes.
1461    *       <br>Therefore, you can find and retrieve messages up the class-hierarchy chain.
1462    * </ul>
1463    * 
1464    * <h5 class='section'>See Also:</h5>
1465    * <ul>
1466    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Messages">Overview &gt; juneau-rest-server &gt; Messages</a>
1467    * </ul>
1468    */
1469   public static final String REST_messages = PREFIX + "messages.lo";
1470   
1471   /**
1472    * Configuration property:  MIME types. 
1473    * 
1474    * <h5 class='section'>Property:</h5>
1475    * <ul>
1476    *    <li><b>Name:</b>  <js>"RestContext.mimeTypes.ss"</js>
1477    *    <li><b>Data type:</b>  <code>Set&lt;String&gt;</code>
1478    *    <li><b>Default:</b>  empty list
1479    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1480    *    <li><b>Annotations:</b> 
1481    *       <ul>
1482    *          <li class='ja'>{@link RestResource#mimeTypes()} 
1483    *       </ul>
1484    *    <li><b>Methods:</b> 
1485    *       <ul>
1486    *          <li class='jm'>{@link RestContextBuilder#mimeTypes(String...)}
1487    *       </ul>
1488    * </ul>
1489    * 
1490    * <h5 class='section'>Description:</h5>
1491    * <p>
1492    * Defines MIME-type file type mappings.
1493    * 
1494    * <p>
1495    * Used for specifying the content type on file resources retrieved through the following methods:
1496    * <ul>
1497    *    <li class='jm'>{@link RestContext#resolveStaticFile(String) RestContext.resolveStaticFile(String)}
1498    *    <li class='jm'>{@link RestRequest#getClasspathReaderResource(String,boolean,MediaType)}
1499    *    <li class='jm'>{@link RestRequest#getClasspathReaderResource(String,boolean)}
1500    *    <li class='jm'>{@link RestRequest#getClasspathReaderResource(String)}
1501    * </ul>
1502    * 
1503    * <p>
1504    * This list appends to the existing list provided by {@link ExtendedMimetypesFileTypeMap}.
1505    * 
1506    * <h5 class='section'>Example:</h5>
1507    * <p class='bcode'>
1508    *    <jc>// Option #1 - Defined via annotation.</jc>
1509    *    <ja>@RestResource</ja>(mimeTypes={<js>"text/plain txt text TXT"</js>})
1510    *    <jk>public class</jk> MyResource {
1511    *       
1512    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
1513    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1514    *          
1515    *          <jc>// Using method on builder.</jc>
1516    *          builder.mimeTypes(<js>"text/plain txt text TXT"</js>);
1517    * 
1518    *          <jc>// Same, but using property.</jc>
1519    *          builder.addTo(<jsf>REST_mimeTypes</jsf>, <js>"text/plain txt text TXT"</js>);
1520    *       }
1521    * 
1522    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
1523    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1524    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1525    *          builder.mimeTypes(<js>"text/plain txt text TXT"</js>);
1526    *       }
1527    *    }
1528    * </p>
1529    * 
1530    * <h5 class='section'>Notes:</h5>
1531    * <ul class='spaced-list'>
1532    *    <li>
1533    *       Values are .mime.types formatted entry string.
1534    *       <br>Example: <js>"image/svg+xml svg"</js>
1535    * </ul>
1536    */
1537   public static final String REST_mimeTypes = PREFIX + "mimeTypes.ss";
1538
1539   /**
1540    * Configuration property:  Java method parameter resolvers.
1541    * 
1542    * <h5 class='section'>Property:</h5>
1543    * <ul>
1544    *    <li><b>Name:</b>  <js>"RestContext.paramResolvers.lo"</js>
1545    *    <li><b>Data type:</b>  <code>List&lt;{@link RestParam} | Class&lt;? <jk>extends</jk> {@link RestParam}&gt;&gt;</code>
1546    *    <li><b>Default:</b>  empty list
1547    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1548    *    <li><b>Annotations:</b>  
1549    *       <ul>
1550    *          <li class='ja'>{@link RestResource#paramResolvers()}
1551    *       </ul>
1552    *    <li><b>Methods:</b> 
1553    *       <ul>
1554    *          <li class='jm'>{@link RestContextBuilder#paramResolvers(Class...)}
1555    *          <li class='jm'>{@link RestContextBuilder#paramResolvers(RestParam...)}
1556    *       </ul>
1557    * </ul>
1558    * 
1559    * <h5 class='section'>Description:</h5>
1560    * <p>
1561    * By default, the Juneau framework will automatically Java method parameters of various types (e.g.
1562    * <code>RestRequest</code>, <code>Accept</code>, <code>Reader</code>).
1563    * This setting allows you to provide your own resolvers for your own class types that you want resolved.
1564    * 
1565    * <p>
1566    * For example, if you want to pass in instances of <code>MySpecialObject</code> to your Java method, define
1567    * the following resolver:
1568    * <p class='bcode'>
1569    *    <jc>// Define a parameter resolver for resolving MySpecialObject objects.</jc>
1570    *    <jk>public class</jk> MyRestParam <jk>extends</jk> RestParam {
1571    * 
1572    *       <jc>// Must have no-arg constructor!</jc>
1573    *       <jk>public</jk> MyRestParam() {
1574    *          <jc>// First two parameters help with Swagger doc generation.</jc>
1575    *          <jk>super</jk>(<jsf>QUERY</jsf>, <js>"myparam"</js>, MySpecialObject.<jk>class</jk>);
1576    *       }
1577    * 
1578    *       <jc>// The method that creates our object.
1579    *       // In this case, we're taking in a query parameter and converting it to our object.</jc>
1580    *       <jk>public</jk> Object resolve(RestRequest req, RestResponse res) <jk>throws</jk> Exception {
1581    *          <jk>return new</jk> MySpecialObject(req.getQuery().get(<js>"myparam"</js>));
1582    *       }
1583    *    }
1584    * 
1585    *    <jc>// Option #1 - Registered via annotation.</jc>
1586    *    <ja>@RestResource</ja>(paramResolvers=MyRestParam.<jk>class</jk>)
1587    *    <jk>public class</jk> MyResource {
1588    * 
1589    *       <jc>// Option #2 - Registered via builder passed in through resource constructor.</jc>
1590    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1591    *          
1592    *          <jc>// Using method on builder.</jc>
1593    *          builder.paramResolvers(MyRestParam.<jk>class</jk>);
1594    * 
1595    *          <jc>// Same, but using property.</jc>
1596    *          builder.addTo(<jsf>REST_paramResolver</jsf>, MyRestParam.<jk>class</jk>);
1597    *       }
1598    * 
1599    *       <jc>// Option #3 - Registered via builder passed in through init method.</jc>
1600    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1601    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1602    *          builder.paramResolvers(MyRestParam.<jk>class</jk>);
1603    *       }
1604    * 
1605    *       <jc>// Now pass it into your method.</jc>
1606    *       <ja>@RestMethod</ja>(...)
1607    *       <jk>public</jk> Object doMyMethod(MySpecialObject mySpeciaObject) {
1608    *          <jc>// Do something with it.</jc>
1609    *       }
1610    *    }
1611    * </p>
1612    * 
1613    * <h5 class='section'>Notes:</h5>
1614    * <ul class='spaced-list'>
1615    *    <li>
1616    *       When defined as a class, the implementation must have one of the following constructors:
1617    *       <ul>
1618    *          <li><code><jk>public</jk> T(BeanContext)</code>
1619    *          <li><code><jk>public</jk> T()</code>
1620    *       </ul>
1621    *    <li>
1622    *       Inner classes of the REST resource class are allowed.
1623    *    <li>
1624    *       Refer to {@link RestParam} for the list of predefined parameter resolvers.
1625    * </ul>
1626    */
1627   public static final String REST_paramResolvers = PREFIX + "paramResolvers.lo";
1628
1629   /**
1630    * Configuration property:  Parsers. 
1631    * 
1632    * <h5 class='section'>Property:</h5>
1633    * <ul>
1634    *    <li><b>Name:</b>  <js>"RestContext.parsers.lo"</js>
1635    *    <li><b>Data type:</b>  <code>List&lt;{@link Parser} | Class&lt;? <jk>extends</jk> {@link Parser}&gt;&gt;</code>
1636    *    <li><b>Default:</b>  empty list
1637    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1638    *    <li><b>Annotations:</b>
1639    *       <ul>
1640    *          <li class='ja'>{@link RestResource#parsers()} 
1641    *          <li class='ja'>{@link RestMethod#parsers()} 
1642    *       </ul>
1643    *    <li><b>Methods:</b> 
1644    *       <ul>
1645    *          <li class='jm'>{@link RestContextBuilder#parsers(Object...)}
1646    *          <li class='jm'>{@link RestContextBuilder#parsers(Class...)}
1647    *          <li class='jm'>{@link RestContextBuilder#parsers(boolean,Object...)}
1648    *       </ul>
1649    * </ul>
1650    * 
1651    * <h5 class='section'>Description:</h5>
1652    * <p>
1653    * Adds class-level parsers to this resource.
1654    * 
1655    * <p>
1656    * Parsers are used to convert the body of HTTP requests into POJOs.  
1657    * <br>Any of the Juneau framework parsers can be used in this setting.
1658    * <br>The parser selected is based on the request <code>Content-Type</code> header matched against the values returned by the following method
1659    * using a best-match algorithm:
1660    * <ul>
1661    *    <li class='jm'>{@link Parser#getMediaTypes()}
1662    * </ul>
1663    * 
1664    * <h5 class='section'>Example:</h5>
1665    * <p class='bcode'>
1666    *    <jc>// Option #1 - Defined via annotation.</jc>
1667    *    <ja>@RestResource</ja>(parsers={JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>})
1668    *    <jk>public class</jk> MyResource {
1669    *       
1670    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
1671    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1672    *          
1673    *          <jc>// Using method on builder.</jc>
1674    *          builder.parsers(JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>);
1675    * 
1676    *          <jc>// Same, but use pre-instantiated parsers.</jc>
1677    *          builder.parsers(JsonParser.<jsf>DEFAULT</jsf>, XmlParser.<jsf>DEFAULT</jsf>);
1678    * 
1679    *          <jc>// Same, but using property.</jc>
1680    *          builder.set(<jsf>REST_parsers</jsf>, JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>);
1681    *       }
1682    * 
1683    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
1684    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1685    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1686    *          builder.parsers(JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>);
1687    *       }
1688    * 
1689    *       <jc>// Override at the method level.</jc>
1690    *       <ja>@RestMethod</ja>(parsers={HtmlParser.<jk>class</jk>})
1691    *       <jk>public</jk> Object myMethod(<ja>@Body</ja> MyPojo myPojo) {
1692    *          <jc>// Do something with your parsed POJO.</jc>
1693    *       }
1694    *    }
1695    * </p>
1696    * 
1697    * <h5 class='section'>Notes:</h5>
1698    * <ul class='spaced-list'>
1699    *    <li>
1700    *       When defined as a class, properties/transforms defined on the resource/method are inherited.
1701    *    <li>
1702    *       When defined as an instance, properties/transforms defined on the resource/method are NOT inherited.
1703    *    <li>
1704    *       Typically, you'll want your resource to extend directly from {@link BasicRestServlet} which comes
1705    *       preconfigured with the following parsers:
1706    *       <ul>
1707    *          <li class='jc'>{@link JsonParser}
1708    *          <li class='jc'>{@link XmlParser}
1709    *          <li class='jc'>{@link HtmlParser}
1710    *          <li class='jc'>{@link UonParser}
1711    *          <li class='jc'>{@link UrlEncodingParser}
1712    *          <li class='jc'>{@link MsgPackParser}
1713    *          <li class='jc'>{@link PlainTextParser}
1714    *       </ul>
1715    * </ul>
1716    * 
1717    * <h5 class='section'>See Also:</h5>
1718    * <ul>
1719    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Parsers">Overview &gt; juneau-rest-server &gt; Parsers</a>
1720    * </ul>
1721    */
1722   public static final String REST_parsers = PREFIX + "parsers.lo";
1723
1724   /**
1725    * Configuration property:  HTTP part parser. 
1726    * 
1727    * <h5 class='section'>Property:</h5>
1728    * <ul>
1729    *    <li><b>Name:</b>  <js>"RestContext.partParser.o"</js>
1730    *    <li><b>Data type:</b>  <code>{@link HttpPartParser} | Class&lt;? <jk>extends</jk> {@link HttpPartParser}&gt;</code>
1731    *    <li><b>Default:</b>  {@link UonPartParser}
1732    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1733    *    <li><b>Annotations:</b> 
1734    *       <ul>
1735    *          <li class='ja'>{@link RestResource#partParser()} 
1736    *       </ul>
1737    *    <li><b>Methods:</b> 
1738    *       <ul>
1739    *          <li class='jm'>{@link RestContextBuilder#partParser(Class)}
1740    *          <li class='jm'>{@link RestContextBuilder#partParser(HttpPartParser)}
1741    *       </ul>
1742    * </ul>
1743    * 
1744    * <h5 class='section'>Description:</h5>
1745    * <p>
1746    * Specifies the {@link HttpPartParser} to use for parsing headers, query/form parameters, and URI parts.
1747    * 
1748    * <p>
1749    * The default value is {@link UonPartParser} which allows for both plain-text and URL-Encoded-Object-Notation values.
1750    * <br>If your parts contain text that can be confused with UON (e.g. <js>"(foo)"</js>), you can switch to 
1751    * {@link SimplePartParser} which treats everything as plain text.
1752    * 
1753    * <h5 class='section'>Example:</h5>
1754    * <p class='bcode'>
1755    *    <jc>// Option #1 - Defined via annotation.</jc>
1756    *    <ja>@RestResource</ja>(partParser=SimplePartParser.<jk>class</jk>)
1757    *    <jk>public class</jk> MyResource {
1758    *       
1759    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
1760    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1761    *          
1762    *          <jc>// Using method on builder.</jc>
1763    *          builder.partParser(SimplePartParser.<jk>class</jk>);
1764    * 
1765    *          <jc>// Same, but using property.</jc>
1766    *          builder.set(<jsf>REST_partParser</jsf>, SimplePartParser.<jk>class</jk>);
1767    *       }
1768    * 
1769    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
1770    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1771    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1772    *          builder.partParser(SimplePartParser.<jk>class</jk>);
1773    *       }
1774    * 
1775    *       <ja>@RestMethod</ja>(...)
1776    *       <jk>public</jk> Object myMethod(<ja>@Header</ja>(<js>"My-Header"</js>) MyParsedHeader h, <ja>@Query</ja>(<js>"myquery"</js>) MyParsedQuery q) {
1777    *          <jc>// Do something with your parsed parts.</jc>
1778    *       }
1779    *    }
1780    * </p>
1781    * 
1782    * <h5 class='section'>Notes:</h5>
1783    * <ul class='spaced-list'>
1784    *    <li>
1785    *       When defined as a class, properties/transforms defined on the resource/method are inherited.
1786    *    <li>
1787    *       When defined as an instance, properties/transforms defined on the resource/method are NOT inherited.
1788    * </ul>
1789    */
1790   public static final String REST_partParser = PREFIX + "partParser.o";
1791
1792   /**
1793    * Configuration property:  HTTP part serializer. 
1794    * 
1795    * <h5 class='section'>Property:</h5>
1796    * <ul>
1797    *    <li><b>Name:</b>  <js>"RestContext.partSerializer.o"</js>
1798    *    <li><b>Data type:</b>  <code>{@link HttpPartSerializer} | Class&lt;? <jk>extends</jk> {@link HttpPartSerializer}&gt;</code>
1799    *    <li><b>Default:</b>  {@link SimpleUonPartSerializer}
1800    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1801    *    <li><b>Annotations:</b> 
1802    *       <ul>
1803    *          <li class='ja'>{@link RestResource#partSerializer()} 
1804    *       </ul>
1805    *    <li><b>Methods:</b> 
1806    *       <ul>
1807    *          <li class='jm'>{@link RestContextBuilder#partSerializer(Class)}
1808    *          <li class='jm'>{@link RestContextBuilder#partSerializer(HttpPartSerializer)}
1809    *       </ul>
1810    * </ul>
1811    * 
1812    * <h5 class='section'>Description:</h5>
1813    * <p>
1814    * Specifies the {@link HttpPartSerializer} to use for serializing headers, query/form parameters, and URI parts.
1815    * 
1816    * <p>
1817    * The default value is {@link SimpleUonPartSerializer} which serializes UON notation for beans and maps, and
1818    * plain text for everything else.
1819    * <br>Other options include:
1820    * <ul>
1821    *    <li class='jc'>{@link SimplePartSerializer} - Always serializes to plain text.
1822    *    <li class='jc'>{@link UonPartSerializer} - Always serializers to UON.
1823    * </ul>
1824    * 
1825    * <h5 class='section'>Example:</h5>
1826    * <p class='bcode'>
1827    *    <jc>// Option #1 - Defined via annotation.</jc>
1828    *    <ja>@RestResource</ja>(partSerializer=SimplePartSerializer.<jk>class</jk>)
1829    *    <jk>public class</jk> MyResource {
1830    *       
1831    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
1832    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1833    *          
1834    *          <jc>// Using method on builder.</jc>
1835    *          builder.partSerializer(SimplePartSerializer.<jk>class</jk>);
1836    * 
1837    *          <jc>// Same, but using property.</jc>
1838    *          builder.set(<jsf>REST_partSerializer</jsf>, SimplePartSerializer.<jk>class</jk>);
1839    *       }
1840    * 
1841    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
1842    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1843    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1844    *          builder.partSerializer(SimplePartSerializer.<jk>class</jk>);
1845    *       }
1846    * 
1847    *       <ja>@RestMethod</ja>(...)
1848    *       <jk>public</jk> Object myMethod(RestResponse res) {
1849    *          <jc>// Set a header to a POJO.</jc>
1850    *          res.setHeader(<js>"My-Header"</js>, <jk>new</jk> MyPojo());
1851    *       }
1852    *    }
1853    * </p>
1854    * 
1855    * <h5 class='section'>Notes:</h5>
1856    * <ul class='spaced-list'>
1857    *    <li>
1858    *       When defined as a class, properties/transforms defined on the resource/method are inherited.
1859    *    <li>
1860    *       When defined as an instance, properties/transforms defined on the resource/method are NOT inherited.
1861    * </ul>
1862    */
1863   public static final String REST_partSerializer = PREFIX + "partSerializer.o";
1864
1865   /**
1866    * Configuration property:  Resource path.   
1867    * 
1868    * <h5 class='section'>Property:</h5>
1869    * <ul>
1870    *    <li><b>Name:</b>  <js>"RestContext.path.s"</js>
1871    *    <li><b>Data type:</b>  <code>String</code>
1872    *    <li><b>Default:</b>  <jk>null</jk>
1873    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1874    *    <li><b>Annotations:</b> 
1875    *       <ul>
1876    *          <li class='ja'>{@link RestResource#path()} 
1877    *       </ul>
1878    *    <li><b>Methods:</b> 
1879    *       <ul>
1880    *          <li class='jm'>{@link RestContextBuilder#path(String)} 
1881    *       </ul>
1882    * </ul>
1883    * 
1884    * <h5 class='section'>Description:</h5>
1885    * <p>
1886    * Identifies the URL subpath relative to the ascendant resource.
1887    * 
1888    * <p>
1889    * This setting is critical for the routing of HTTP requests from ascendant to child resources.
1890    * 
1891    * <h5 class='section'>Example:</h5>
1892    * <p class='bcode'>
1893    *    <jc>// Option #1 - Defined via annotation.</jc>
1894    *    <ja>@RestResource</ja>(path=<js>"/myResource"</js>)
1895    *    <jk>public class</jk> MyResource {
1896    *       
1897    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
1898    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1899    *          
1900    *          <jc>// Using method on builder.</jc>
1901    *          builder.path(<js>"/myResource"</js>);
1902    * 
1903    *          <jc>// Same, but using property.</jc>
1904    *          builder.set(<jsf>REST_path</jsf>, <js>"/myResource"</js>);
1905    *       }
1906    * 
1907    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
1908    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1909    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1910    *          builder.path(<js>"/myResource"</js>);
1911    *       }
1912    *    }
1913    * </p>
1914    * 
1915    * <p>
1916    * <h5 class='section'>Notes:</h5>
1917    * <ul class='spaced-list'>
1918    *    <li>
1919    *       This annotation is ignored on top-level servlets (i.e. servlets defined in <code>web.xml</code> files).
1920    *       <br>Therefore, implementers can optionally specify a path value for documentation purposes.
1921    *    <li>
1922    *       Typically, this setting is only applicable to resources defined as children through the 
1923    *       {@link RestResource#children() @RestResource.children()} annotation.
1924    *       <br>However, it may be used in other ways (e.g. defining paths for top-level resources in microservices).
1925    *    <li>
1926    *       Slashes are trimmed from the path ends.
1927    *       <br>As a convention, you may want to start your path with <js>'/'</js> simple because it make it easier to read.
1928    *    <li>
1929    *       This path is available through the following method:
1930    *       <ul>
1931    *          <li class='jm'>{@link RestContext#getPath() RestContext.getPath()}
1932    *       </ul>
1933    * </ul>
1934    */
1935   public static final String REST_path = PREFIX + "path.s";
1936
1937   /**
1938    * Configuration property:  Render response stack traces in responses.
1939    * 
1940    * <h5 class='section'>Property:</h5>
1941    * <ul>
1942    *    <li><b>Name:</b>  <js>"RestContext.renderResponseStackTraces.b"</js>
1943    *    <li><b>Data type:</b>  <code>Boolean</code>
1944    *    <li><b>Default:</b>  <jk>false</jk>
1945    *    <li><b>Session-overridable:</b>  <jk>false</jk>
1946    *    <li><b>Annotations:</b>  
1947    *       <ul>
1948    *          <li class='ja'>{@link RestResource#renderResponseStackTraces()}
1949    *       </ul>
1950    *    <li><b>Methods:</b>  
1951    *       <ul>
1952    *          <li class='jm'>{@link RestContextBuilder#renderResponseStackTraces(boolean)}
1953    *          <li class='jm'>{@link RestContextBuilder#renderResponseStackTraces()}
1954    *       </ul>
1955    * </ul>
1956    * 
1957    * <h5 class='section'>Description:</h5>
1958    * <p>
1959    * Render stack traces in HTTP response bodies when errors occur.
1960    * 
1961    * <h5 class='section'>Example:</h5>
1962    * <p class='bcode'>
1963    *    <jc>// Option #1 - Defined via annotation.</jc>
1964    *    <ja>@RestResource</ja>(renderResponseStackTraces=<jk>true</jk>)
1965    *    <jk>public class</jk> MyResource {
1966    *       
1967    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
1968    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
1969    *          
1970    *          <jc>// Using method on builder.</jc>
1971    *          builder.renderResponseStackTraces();
1972    * 
1973    *          <jc>// Same, but using property.</jc>
1974    *          builder.set(<jsf>REST_renderResponseStackTraces</jsf>, <jk>true</jk>);
1975    *       }
1976    * 
1977    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
1978    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
1979    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
1980    *          builder.renderResponseStackTraces();
1981    *       }
1982    *    }
1983    * </p>
1984    * 
1985    * <h5 class='section'>Notes:</h5>
1986    * <ul class='spaced-list'>
1987    *    <li>
1988    *       Useful for debugging, although allowing stack traces to be rendered may cause security concerns so use
1989    *       caution when enabling.
1990    *    <li>
1991    *       This setting is available through the following method:
1992    *       <ul>
1993    *          <li class='jm'>{@link RestContext#isRenderResponseStackTraces() RestContext.isRenderResponseStackTraces()}
1994    *       </ul>
1995    *       That method is used by {@link BasicRestCallHandler#renderError(HttpServletRequest, HttpServletResponse, RestException)}.
1996    * </ul>
1997    */
1998   public static final String REST_renderResponseStackTraces = PREFIX + "renderResponseStackTraces.b";
1999   
2000   /**
2001    * Configuration property:  REST resource resolver.
2002    * 
2003    * <h5 class='section'>Property:</h5>
2004    * <ul>
2005    *    <li><b>Name:</b>  <js>"RestContext.resourceResolver.o"</js>
2006    *    <li><b>Data type:</b>  <code>{@link RestResourceResolver} | Class&lt;? <jk>extends</jk> {@link RestResourceResolver}&gt;</code>
2007    *    <li><b>Default:</b>  {@link BasicRestResourceResolver}
2008    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2009    *    <li><b>Annotations:</b> 
2010    *       <ul>
2011    *          <li class='ja'>{@link RestResource#resourceResolver()} 
2012    *       </ul>
2013    *    <li><b>Methods:</b>  
2014    *       <ul>
2015    *          <li class='jm'>{@link RestContextBuilder#resourceResolver(Class)}
2016    *          <li class='jm'>{@link RestContextBuilder#resourceResolver(RestResourceResolver)}
2017    *       </ul>
2018    * </ul>
2019    * 
2020    * <h5 class='section'>Description:</h5>
2021    * <p>
2022    * The resolver used for resolving instances of child resources.
2023    * 
2024    * <p>
2025    * Can be used to provide customized resolution of REST resource class instances (e.g. resources retrieve from Spring).
2026    * 
2027    * <h5 class='section'>Example:</h5>
2028    * <p class='bcode'>
2029    *    <jc>// Our custom resource resolver. </jc>
2030    *    <jk>public class</jk> MyResourceResolver <jk>extends</jk> RestResourceResolverSimple {
2031    *    
2032    *       <ja>@Override</ja>
2033    *       <jk>public</jk> Object resolve(Class&lt;?&gt; resourceType, RestContextBuilder builder) <jk>throws</jk> Exception {
2034    *          Object resource = <jsm>findOurResourceSomehow</jsm>(resourceType);
2035    * 
2036    *          <jc>// If we can't resolve it, use default resolution.</jc>
2037    *          <jk>if</jk> (resource == <jk>null</jk>) 
2038    *             resource = <jk>super</jk>.resolve(resourceType, builder);
2039    *       
2040    *          <jk>return</jk> resource;
2041    *       }
2042    *    }
2043    * 
2044    *    <jc>// Option #1 - Defined via annotation.</jc>
2045    *    <ja>@RestResource</ja>(resourceResolver=MyResourceResolver.<jk>class</jk>)
2046    *    <jk>public class</jk> MyResource {
2047    *       
2048    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
2049    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
2050    *          
2051    *          <jc>// Using method on builder.</jc>
2052    *          builder.resourceResolver(MyResourceResolver.<jk>class</jk>);
2053    * 
2054    *          <jc>// Same, but using property.</jc>
2055    *          builder.set(<jsf>REST_resourceResolver</jsf>, MyResourceResolver.<jk>class</jk>);
2056    *       }
2057    * 
2058    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
2059    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
2060    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
2061    *          builder.resourceResolver(MyResourceResolver.<jk>class</jk>);
2062    *       }
2063    *    }
2064    * </p>
2065    * 
2066    * <h5 class='section'>Notes:</h5>
2067    * <ul class='spaced-list'>
2068    *    <li>
2069    *       Unless overridden, resource resolvers are inherited from ascendant resources.
2070    *    <li>
2071    *       When defined as a class, the implementation must have one of the following constructors:
2072    *       <ul>
2073    *          <li><code><jk>public</jk> T(RestContext)</code>
2074    *          <li><code><jk>public</jk> T()</code>
2075    *       </ul>
2076    *    <li>
2077    *       Inner classes of the REST resource class are allowed.
2078    * </ul>
2079    * 
2080    * <h5 class='section'>See Also:</h5>
2081    * <ul>
2082    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.ResourceResolvers">Overview &gt; juneau-rest-server &gt; Resource Resolvers</a>
2083    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Injection">Overview &gt; juneau-rest-server &gt; Using with Spring and Injection frameworks</a>
2084    * </ul>
2085    */
2086   public static final String REST_resourceResolver = PREFIX + "resourceResolver.o";
2087
2088   /**
2089    * Configuration property:  Response handlers.
2090    * 
2091    * <h5 class='section'>Property:</h5>
2092    * <ul>
2093    *    <li><b>Name:</b>  <js>"RestContext.responseHandlers.lo"</js>
2094    *    <li><b>Data type:</b>  <code>List&lt;{@link ResponseHandler} | Class&lt;? <jk>extends</jk> {@link ResponseHandler}&gt;&gt;</code>
2095    *    <li><b>Default:</b>  empty list
2096    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2097    *    <li><b>Annotations:</b> 
2098    *       <ul>
2099    *          <li class='ja'>{@link RestResource#responseHandlers()} 
2100    *       </ul>
2101    *    <li><b>Methods:</b> 
2102    *       <ul>
2103    *          <li class='jm'>{@link RestContextBuilder#responseHandlers(Class...)}
2104    *          <li class='jm'>{@link RestContextBuilder#responseHandlers(ResponseHandler...)}
2105    *       </ul>
2106    * </ul>
2107    * 
2108    * <h5 class='section'>Description:</h5>
2109    * <p>
2110    * Specifies a list of {@link ResponseHandler} classes that know how to convert POJOs returned by REST methods or
2111    * set via {@link RestResponse#setOutput(Object)} into appropriate HTTP responses.
2112    * 
2113    * <p>
2114    * By default, the following response handlers are provided out-of-the-box:
2115    * <ul>
2116    *    <li class='jc'>{@link StreamableHandler} - {@link Streamable} objects.
2117    *    <li class='jc'>{@link WritableHandler} - {@link Writable} objects.
2118    *    <li class='jc'>{@link ReaderHandler} - {@link Reader} objects.
2119    *    <li class='jc'>{@link InputStreamHandler} - {@link InputStream} objects.
2120    *    <li class='jc'>{@link RedirectHandler} - {@link Redirect} objects. 
2121    *    <li class='jc'>{@link ZipFileListResponseHandler} - {@link ZipFileList} objects. 
2122    *    <li class='jc'>{@link DefaultHandler} - All other POJOs.
2123    * </ul>
2124    * 
2125    * <h5 class='section'>Example:</h5>
2126    * <p class='bcode'>
2127    *    <jc>// Our custom response handler for MySpecialObject objects. </jc>
2128    *    <jk>public class</jk> MyResponseHandler <jk>implements</jk> ResponseHandler {
2129    *    
2130    *       <ja>@Override</ja> 
2131    *       <jk>public boolean</jk> handle(RestRequest req, RestResponse res, Object output) <jk>throws</jk> IOException, RestException {
2132    *          <jk>if</jk> (output <jk>instanceof</jk> MySpecialObject) {
2133    *             <jk>try</jk> (Writer w = res.getNegotiatedWriter()) {
2134    *                <jc>//Pipe it to the writer ourselves.</jc>
2135    *             }
2136    *             <jk>return true</jk>;  <jc>// We handled it.</jc>
2137    *          }
2138    *          <jk>return false</jk>; <jc>// We didn't handle it.</jc>
2139    *       }
2140    *    }
2141    * 
2142    *    <jc>// Option #1 - Defined via annotation.</jc>
2143    *    <ja>@RestResource</ja>(responseHandlers=MyResponseHandler.<jk>class</jk>)
2144    *    <jk>public class</jk> MyResource {
2145    *       
2146    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
2147    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
2148    *          
2149    *          <jc>// Using method on builder.</jc>
2150    *          builder.responseHandlers(MyResponseHandler.<jk>class</jk>);
2151    * 
2152    *          <jc>// Same, but using property.</jc>
2153    *          builder.addTo(<jsf>REST_responseHandlers</jsf>, MyResponseHandler.<jk>class</jk>);
2154    *       }
2155    * 
2156    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
2157    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
2158    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
2159    *          builder.responseHandlers(MyResponseHandler.<jk>class</jk>);
2160    *       }
2161    * 
2162    *       <ja>@RestMethod</ja>(...)
2163    *       <jk>public</jk> Object myMethod() {
2164    *          <jc>// Return a special object for our handler.</jc>
2165    *          <jk>return new</jk> MySpecialObject();
2166    *       }
2167    *    }
2168    * </p>
2169    * 
2170    * <h5 class='section'>Notes:</h5>
2171    * <ul class='spaced-list'>
2172    *    <li>
2173    *       Response handlers resolvers are always inherited from ascendant resources.
2174    *    <li>
2175    *       When defined as a class, the implementation must have one of the following constructors:
2176    *       <ul>
2177    *          <li><code><jk>public</jk> T(RestContext)</code>
2178    *          <li><code><jk>public</jk> T()</code>
2179    *       </ul>
2180    *    <li>
2181    *       Inner classes of the REST resource class are allowed.
2182    * </ul>
2183    */
2184   public static final String REST_responseHandlers = PREFIX + "responseHandlers.lo";
2185
2186   /**
2187    * Configuration property:  Serializers. 
2188    * 
2189    * <h5 class='section'>Property:</h5>
2190    * <ul>
2191    *    <li><b>Name:</b>  <js>"RestContext.serializers.lo"</js>
2192    *    <li><b>Data type:</b>  <code>List&lt;{@link Serializer} | Class&lt;? <jk>extends</jk> {@link Serializer}&gt;&gt;</code>
2193    *    <li><b>Default:</b>  empty list
2194    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2195    *    <li><b>Annotations:</b> 
2196    *       <ul>
2197    *          <li class='ja'>{@link RestResource#serializers()} 
2198    *          <li class='ja'>{@link RestMethod#serializers()} 
2199    *       </ul>
2200    *    <li><b>Methods:</b> 
2201    *       <ul>
2202    *          <li class='jm'>{@link RestContextBuilder#serializers(Object...)}
2203    *          <li class='jm'>{@link RestContextBuilder#serializers(Class...)}
2204    *          <li class='jm'>{@link RestContextBuilder#serializers(boolean,Object...)}
2205    *       </ul>
2206    * </ul>
2207    * 
2208    * <h5 class='section'>Description:</h5>
2209    * <p>
2210    * Adds class-level serializers to this resource.
2211    * 
2212    * <p>
2213    * Serializer are used to convert POJOs to HTTP response bodies.  
2214    * <br>Any of the Juneau framework serializers can be used in this setting.
2215    * <br>The serializer selected is based on the request <code>Accept</code> header matched against the values returned by the following method
2216    * using a best-match algorithm:
2217    * <ul>
2218    *    <li class='jm'>{@link Serializer#getMediaTypes()}
2219    * </ul>
2220    * 
2221    * <h5 class='section'>Example:</h5>
2222    * <p class='bcode'>
2223    *    <jc>// Option #1 - Defined via annotation.</jc>
2224    *    <ja>@RestResource</ja>(serializers={JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>})
2225    *    <jk>public class</jk> MyResource {
2226    *       
2227    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
2228    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
2229    *          
2230    *          <jc>// Using method on builder.</jc>
2231    *          builder.serializers(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>);
2232    * 
2233    *          <jc>// Same, but use pre-instantiated parsers.</jc>
2234    *          builder.serializers(JsonSerializer.<jsf>DEFAULT</jsf>, XmlSerializer.<jsf>DEFAULT</jsf>);
2235    * 
2236    *          <jc>// Same, but using property.</jc>
2237    *          builder.set(<jsf>REST_serializers</jsf>, JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>);
2238    *       }
2239    * 
2240    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
2241    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
2242    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
2243    *          builder.serializers(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>);
2244    *       }
2245    * 
2246    *       <jc>// Override at the method level.</jc>
2247    *       <ja>@RestMethod</ja>(serializers={HtmlSerializer.<jk>class</jk>})
2248    *       <jk>public</jk> MyPojo myMethod() {
2249    *          <jc>// Return a POJO to be serialized.</jc>
2250    *          <jk>return new</jk> MyPojo(); 
2251    *       }
2252    *    }
2253    * </p>
2254    * 
2255    * <h5 class='section'>Notes:</h5>
2256    * <ul class='spaced-list'>
2257    *    <li>
2258    *       When defined as a class, properties/transforms defined on the resource/method are inherited.
2259    *    <li>
2260    *       When defined as an instance, properties/transforms defined on the resource/method are NOT inherited.
2261    *    <li>
2262    *       Typically, you'll want your resource to extend directly from {@link BasicRestServlet} which comes
2263    *       preconfigured with the following serializers:
2264    *       <ul>
2265    *          <li class='jc'>{@link HtmlDocSerializer}
2266    *          <li class='jc'>{@link HtmlStrippedDocSerializer}
2267    *          <li class='jc'>{@link HtmlSchemaDocSerializer}
2268    *          <li class='jc'>{@link JsonSerializer}
2269    *          <li class='jc'>{@link org.apache.juneau.json.JsonSerializer.Simple}
2270    *          <li class='jc'>{@link JsonSchemaSerializer}
2271    *          <li class='jc'>{@link XmlDocSerializer}
2272    *          <li class='jc'>{@link XmlSchemaDocSerializer}
2273    *          <li class='jc'>{@link UonSerializer}
2274    *          <li class='jc'>{@link UrlEncodingSerializer}
2275    *          <li class='jc'>{@link MsgPackSerializer}
2276    *          <li class='jc'>{@link SoapXmlSerializer}
2277    *          <li class='jc'>{@link PlainTextSerializer}
2278    *       </ul>
2279    * </ul>
2280    * 
2281    * <h5 class='section'>See Also:</h5>
2282    * <ul>
2283    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Serializers">Overview &gt; juneau-rest-server &gt; Serializers</a>
2284    * </ul>
2285    * <p>
2286    */
2287   public static final String REST_serializers = PREFIX + "serializers.lo";
2288
2289   /**
2290    * Configuration property:  Static file response headers. 
2291    * 
2292    * <h5 class='section'>Property:</h5>
2293    * <ul>
2294    *    <li><b>Name:</b>  <js>"RestContext.staticFileResponseHeaders.omo"</js>
2295    *    <li><b>Data type:</b>  <code>Map&lt;String,String&gt;</code>
2296    *    <li><b>Default:</b>  <code>{<js>'Cache-Control'</js>: <js>'max-age=86400, public</js>}</code>
2297    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2298    *    <li><b>Annotations:</b> 
2299    *       <ul>
2300    *          <li class='ja'>{@link RestResource#staticFileResponseHeaders()} 
2301    *       </ul>
2302    *    <li><b>Methods:</b> 
2303    *       <ul>
2304    *          <li class='jm'>{@link RestContextBuilder#staticFileResponseHeaders(boolean,Map)}
2305    *          <li class='jm'>{@link RestContextBuilder#staticFileResponseHeaders(String...)}
2306    *          <li class='jm'>{@link RestContextBuilder#staticFileResponseHeader(String,String)}
2307    *       </ul>
2308    * </ul>
2309    * 
2310    * <h5 class='section'>Description:</h5>
2311    * <p>
2312    * Used to customize the headers on responses returned for statically-served files.
2313    * 
2314    * <h5 class='section'>Example:</h5>
2315    * <p class='bcode'>
2316    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
2317    *    <ja>@RestResource</ja>(
2318    *       staticFileResponseHeaders={
2319    *          <js>"Cache-Control: $C{REST/cacheControl,nocache}"</js>,
2320    *          <js>"My-Header: $C{REST/myHeaderValue}"</js>
2321    *       }
2322    *    )
2323    *    <jk>public class</jk> MyResource {
2324    * 
2325    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
2326    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
2327    *          
2328    *          <jc>// Using method on builder.</jc>
2329    *          builder
2330    *             .staticFileResponseHeader(<js>"Cache-Control"</js>, <js>"nocache"</js>);
2331    *             .staticFileResponseHeaders(<js>"My-Header: foo"</js>);
2332    * 
2333    *          <jc>// Same, but using property.</jc>
2334    *          builder
2335    *             .addTo(<jsf>REST_staticFileResponseHeaders</jsf>, <js>"Cache-Control"</js>, <js>"nocache"</js>);
2336    *             .addTo(<jsf>REST_staticFileResponseHeaders</jsf>, <js>"My-Header"</js>, <js>"foo"</js>);
2337    *       }
2338    * 
2339    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
2340    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
2341    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
2342    *          builder.staticFileResponseHeader(<js>"Cache-Control"</js>, <js>"nocache"</js>);
2343    *       }
2344    *    }
2345    * </p>
2346    * 
2347    * <h5 class='section'>See Also:</h5>
2348    * <ul>
2349    *    <li class='jf'>{@link #REST_staticFiles} for information about statically-served files.
2350    * </ul>
2351    */
2352   public static final String REST_staticFileResponseHeaders = PREFIX + "staticFileResponseHeaders.omo";
2353   
2354   /**
2355    * Configuration property:  Static file mappings. 
2356    * 
2357    * <h5 class='section'>Property:</h5>
2358    * <ul>
2359    *    <li><b>Name:</b>  <js>"RestContext.staticFiles.lo"</js>
2360    *    <li><b>Data type:</b>  <code>List&lt;StaticFileMapping&gt;</code>
2361    *    <li><b>Default:</b>  <jk>null</jk>
2362    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2363    *    <li><b>Annotations:</b> 
2364    *       <ul>
2365    *          <li class='ja'>{@link RestResource#staticFiles()} 
2366    *       </ul>
2367    *    <li><b>Methods:</b> 
2368    *       <ul>
2369    *          <li class='jm'>{@link RestContextBuilder#staticFiles(String)},
2370    *          <li class='jm'>{@link RestContextBuilder#staticFiles(Class,String)}
2371    *          <li class='jm'>{@link RestContextBuilder#staticFiles(String,String)}
2372    *          <li class='jm'>{@link RestContextBuilder#staticFiles(Class,String,String)} 
2373    *          <li class='jm'>{@link RestContextBuilder#staticFiles(StaticFileMapping...)} 
2374    *       </ul>
2375    * </ul>
2376    * 
2377    * <h5 class='section'>Description:</h5>
2378    * <p>
2379    * Used to define paths and locations of statically-served files such as images or HTML documents
2380    * from the classpath or file system.
2381    * 
2382    * <p>
2383    * An example where this class is used is in the {@link RestResource#staticFiles} annotation:
2384    * <p class='bcode'>
2385    *    <jk>package</jk> com.foo.mypackage;
2386    * 
2387    *    <ja>@RestResource</ja>(
2388    *       path=<js>"/myresource"</js>,
2389    *       staticFiles={
2390    *          <js>"htdocs:docs"</js>,
2391    *          <js>"styles:styles"</js>
2392    *       }
2393    *    )
2394    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {...}
2395    * </p>
2396    * 
2397    * <p>
2398    * In the example above, given a GET request to the following URL...
2399    * <p class='bcode'>
2400    *    /myresource/htdocs/foobar.html
2401    * </p>
2402    * <br>...the servlet will attempt to find the <code>foobar.html</code> file in the following ordered locations:
2403    * <ol class='spaced-list'>
2404    *    <li><code>com.foo.mypackage.docs</code> package.
2405    *    <li><code>[working-dir]/docs</code> directory.
2406    * </ol>
2407    * 
2408    * <h5 class='section'>See Also:</h5>
2409    * <ul>
2410    *    <li class='jf'>{@link #REST_classpathResourceFinder} for configuring how classpath resources are located and retrieved.
2411    *    <li class='jf'>{@link #REST_mimeTypes} for configuring the media types based on file extension.
2412    *    <li class='jf'>{@link #REST_staticFileResponseHeaders} for configuring response headers on statically served files.
2413    *    <li class='jf'>{@link #REST_useClasspathResourceCaching} for configuring static file caching.
2414    *    <li class='jm'>{@link RestContext#getClasspathResource(String,Locale)} for retrieving static files.
2415    * </ul>
2416    * 
2417    * <h5 class='section'>Notes:</h5>
2418    * <ul class='spaced-list'>
2419    *    <li>
2420    *       Mappings are cumulative from super classes.  
2421    *    <li>
2422    *       Child resources can override mappings made on parent class resources.
2423    * </ul>
2424    */
2425   public static final String REST_staticFiles = PREFIX + "staticFiles.lo";
2426   
2427   /**
2428    * Configuration property:  Supported accept media types.
2429    * 
2430    * <h5 class='section'>Property:</h5>
2431    * <ul>
2432    *    <li><b>Name:</b>  <js>"RestContext.produces.ls"</js>
2433    *    <li><b>Data type:</b>  <code>List&lt;String&gt;</code>
2434    *    <li><b>Default:</b>  empty list
2435    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2436    *    <li><b>Annotations:</b>
2437    *       <ul>
2438    *          <li class='ja'>{@link RestResource#produces()}
2439    *          <li class='ja'>{@link RestMethod#produces()}
2440    *       </ul> 
2441    *    <li><b>Methods:</b>  
2442    *       <ul>
2443    *          <li class='jm'>{@link RestContextBuilder#produces(boolean,String...)}
2444    *          <li class='jm'>{@link RestContextBuilder#produces(boolean,MediaType...)}
2445    *       </ul>
2446    * </ul>
2447    * 
2448    * <h5 class='section'>Description:</h5>
2449    * <p>
2450    * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource.
2451    * <br>An example where this might be useful if you have serializers registered that handle media types that you
2452    * don't want exposed in the Swagger documentation.
2453    * 
2454    * <h5 class='section'>Example:</h5>
2455    * <p class='bcode'>
2456    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
2457    *    <ja>@RestResource</ja>(produces={<js>"$C{REST/supportedProduces,application/json}"</js>})
2458    *    <jk>public class</jk> MyResource {
2459    * 
2460    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
2461    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
2462    *          
2463    *          <jc>// Using method on builder.</jc>
2464    *          builder.produces(<jk>false</jk>, <js>"application/json"</js>)
2465    * 
2466    *          <jc>// Same, but using property.</jc>
2467    *          builder.set(<jsf>REST_produces</jsf>, <js>"application/json"</js>);
2468    *       }
2469    * 
2470    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
2471    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
2472    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
2473    *          builder.produces(<jk>false</jk>, <js>"application/json"</js>);
2474    *       }
2475    *    }
2476    * </p>
2477    * 
2478    * <p>
2479    * This affects the returned values from the following:
2480    * <ul>
2481    *    <li class='jm'>{@link RestContext#getProduces() RestContext.getProduces()}
2482    *    <li class='jm'>{@link RestRequest#getProduces()}
2483    *    <li class='jm'>{@link RestInfoProvider#getSwagger(RestRequest)} - Affects produces field.
2484    * </ul>
2485    */
2486   public static final String REST_produces = PREFIX + "produces.ls";
2487
2488   /**
2489    * Configuration property:  Supported content media types.
2490    * 
2491    * <h5 class='section'>Property:</h5>
2492    * <ul>
2493    *    <li><b>Name:</b>  <js>"RestContext.consumes.ls"</js>
2494    *    <li><b>Data type:</b>  <code>List&lt;String&gt;</code>
2495    *    <li><b>Default:</b>  empty list
2496    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2497    *    <li><b>Annotations:</b>
2498    *       <ul>
2499    *          <li class='ja'>{@link RestResource#consumes()}
2500    *          <li class='ja'>{@link RestMethod#consumes()}
2501    *       </ul> 
2502    *    <li><b>Methods:</b>  
2503    *       <ul>
2504    *          <li class='jm'>{@link RestContextBuilder#consumes(boolean,String...)}
2505    *          <li class='jm'>{@link RestContextBuilder#consumes(boolean,MediaType...)}
2506    *       </ul>
2507    * </ul>
2508    * 
2509    * <h5 class='section'>Description:</h5>
2510    * <p>
2511    * Overrides the media types inferred from the parsers that identify what media types can be consumed by the resource.
2512    * <br>An example where this might be useful if you have parsers registered that handle media types that you
2513    * don't want exposed in the Swagger documentation.
2514    * 
2515    * <h5 class='section'>Example:</h5>
2516    * <p class='bcode'>
2517    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
2518    *    <ja>@RestResource</ja>(consumes={<js>"$C{REST/supportedConsumes,application/json}"</js>})
2519    *    <jk>public class</jk> MyResource {
2520    * 
2521    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
2522    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
2523    *          
2524    *          <jc>// Using method on builder.</jc>
2525    *          builder.consumes(<jk>false</jk>, <js>"application/json"</js>)
2526    * 
2527    *          <jc>// Same, but using property.</jc>
2528    *          builder.set(<jsf>REST_consumes</jsf>, <js>"application/json"</js>);
2529    *       }
2530    * 
2531    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
2532    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
2533    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
2534    *          builder.consumes(<jk>false</jk>, <js>"application/json"</js>);
2535    *       }
2536    *    }
2537    * </p>
2538    * 
2539    * <p>
2540    * This affects the returned values from the following:
2541    * <ul>
2542    *    <li class='jm'>{@link RestContext#getConsumes() RestContext.getConsumes()}
2543    *    <li class='jm'>{@link RestRequest#getConsumes()}
2544    *    <li class='jm'>{@link RestInfoProvider#getSwagger(RestRequest)} - Affects consumes field.
2545    * </ul>
2546    */
2547   public static final String REST_consumes = PREFIX + "consumes.ls";
2548   
2549   /**
2550    * Configuration property:  Use classpath resource caching. 
2551    * 
2552    * <h5 class='section'>Property:</h5>
2553    * <ul>
2554    *    <li><b>Name:</b>  <js>"RestContext.useClasspathResourceCaching.b"</js>
2555    *    <li><b>Data type:</b>  <code>Boolean</code>
2556    *    <li><b>Default:</b>  <jk>true</jk>
2557    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2558    *    <li><b>Annotations:</b> 
2559    *       <ul>
2560    *          <li class='ja'>{@link RestResource#useClasspathResourceCaching()} 
2561    *       </ul>
2562    *    <li><b>Methods:</b> 
2563    *       <ul>
2564    *          <li class='jm'>{@link RestContextBuilder#useClasspathResourceCaching(boolean)}
2565    *       </ul>
2566    * </ul>
2567    * 
2568    * <h5 class='section'>Description:</h5>
2569    * <p>
2570    * When enabled, resources retrieved via {@link RestContext#getClasspathResource(String, Locale)} (and related 
2571    * methods) will be cached in memory to speed subsequent lookups.
2572    * 
2573    * <h5 class='section'>Example:</h5>
2574    * <p class='bcode'>
2575    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
2576    *    <ja>@RestResource</ja>(useClasspathResourceCaching=<js>"$C{REST/useClasspathResourceCaching,false}"</js>)
2577    *    <jk>public class</jk> MyResource {
2578    * 
2579    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
2580    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
2581    *          
2582    *          <jc>// Using method on builder.</jc>
2583    *          builder.useClasspathResourceCaching(<jk>false</jk>)
2584    * 
2585    *          <jc>// Same, but using property.</jc>
2586    *          builder.set(<jsf>REST_useClasspathResourceCaching</jsf>, <jk>false</jk>);
2587    *       }
2588    * 
2589    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
2590    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
2591    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
2592    *          builder.useClasspathResourceCaching(<jk>false</jk>)
2593    *       }
2594    *    }
2595    * </p>
2596    * 
2597    * <h5 class='section'>See Also:</h5>
2598    * <ul>
2599    *    <li class='jf'>{@link #REST_staticFiles} for information about static files.
2600    * </ul>
2601    */
2602   public static final String REST_useClasspathResourceCaching = PREFIX + "useClasspathResourceCaching.b";
2603
2604   /**
2605    * Configuration property:  Use stack trace hashes.
2606    * 
2607    * <h5 class='section'>Property:</h5>
2608    * <ul>
2609    *    <li><b>Name:</b>  <js>"RestContext.useStackTraceHashes.b"</js>
2610    *    <li><b>Data type:</b>  <code>Boolean</code>
2611    *    <li><b>Default:</b>  <jk>true</jk>
2612    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2613    *    <li><b>Annotations:</b>  
2614    *       <ul>
2615    *          <li class='ja'>{@link RestResource#useStackTraceHashes()}
2616    *       </ul>
2617    *    <li><b>Methods:</b>  
2618    *       <ul>
2619    *          <li class='jm'>{@link RestContextBuilder#useStackTraceHashes(boolean)}
2620    *       </ul>
2621    * </ul>
2622    * 
2623    * <h5 class='section'>Description:</h5>
2624    * <p>
2625    * When enabled, the number of times an exception has occurred will be tracked based on stack trace hashsums.
2626    * 
2627    * <p>
2628    * Affects the following methods:
2629    * <ul>
2630    *    <li class='jm'>{@link RestContext#getStackTraceOccurrence(Throwable) RestContext.getStackTraceOccurrance(Throwable)}
2631    *    <li class='jm'>{@link RestCallHandler#handleError(HttpServletRequest, HttpServletResponse, RestException)}
2632    *    <li class='jm'>{@link RestException#getOccurrence()} - Returns the number of times this exception occurred.
2633    * </ul>
2634    * 
2635    * <h5 class='section'>Example:</h5>
2636    * <p class='bcode'>
2637    *    <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc>
2638    *    <ja>@RestResource</ja>(useStackTraceHashes=<js>"$C{REST/useStackTraceHashes,false}"</js>)
2639    *    <jk>public class</jk> MyResource {
2640    * 
2641    *       <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc>
2642    *       <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception {
2643    *          
2644    *          <jc>// Using method on builder.</jc>
2645    *          builder.useStackTraceHashes(<jk>false</jk>)
2646    * 
2647    *          <jc>// Same, but using property.</jc>
2648    *          builder.set(<jsf>REST_useStackTraceHashes</jsf>, <jk>false</jk>);
2649    *       }
2650    * 
2651    *       <jc>// Option #3 - Defined via builder passed in through init method.</jc>
2652    *       <ja>@RestHook</ja>(<jsf>INIT</jsf>)
2653    *       <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception {
2654    *          builder.useStackTraceHashes(<jk>false</jk>)
2655    *       }
2656    *    }
2657    * </p>
2658    */
2659   public static final String REST_useStackTraceHashes = PREFIX + "useStackTraceHashes.b";
2660   
2661   /**
2662    * Configuration property:  HTML Widgets. 
2663    * 
2664    * <h5 class='section'>Property:</h5>
2665    * <ul>
2666    *    <li><b>Name:</b>  <js>"RestContext.widgets.lo"</js>
2667    *    <li><b>Data type:</b>  <code>List&lt;{@link Widget} | Class&lt;? <jk>extends</jk> {@link Widget}&gt;&gt;</code>
2668    *    <li><b>Default:</b>  empty list
2669    *    <li><b>Session-overridable:</b>  <jk>false</jk>
2670    *    <li><b>Annotations:</b> 
2671    *       <ul>
2672    *          <li class='ja'>{@link HtmlDoc#widgets()} 
2673    *       </ul>
2674    *    <li><b>Methods:</b> 
2675    *       <ul>
2676    *          <li class='jm'>{@link RestContextBuilder#widgets(Class...)}
2677    *          <li class='jm'>{@link RestContextBuilder#widgets(Widget...)}
2678    *          <li class='jm'>{@link RestContextBuilder#widgets(boolean,Widget...)}
2679    *       </ul>
2680    * </ul>
2681    * 
2682    * <h5 class='section'>Description:</h5>
2683    * <p>
2684    * Defines widgets that can be used in conjunction with string variables of the form <js>"$W{name}"</js>to quickly
2685    * generate arbitrary replacement text.
2686    * 
2687    * Widgets resolve the following variables:
2688    * <ul class='spaced-list'>
2689    *    <li><js>"$W{name}"</js> - Contents returned by {@link Widget#getHtml(RestRequest)}.
2690    *    <li><js>"$W{name.script}"</js> - Contents returned by {@link Widget#getScript(RestRequest)}.
2691    *       <br>The script contents are automatically inserted into the <xt>&lt;head/script&gt;</xt> section
2692    *           in the HTML page.
2693    *    <li><js>"$W{name.style}"</js> - Contents returned by {@link Widget#getStyle(RestRequest)}.
2694    *       <br>The styles contents are automatically inserted into the <xt>&lt;head/style&gt;</xt> section
2695    *           in the HTML page.
2696    * </ul>
2697    * 
2698    * <p>
2699    * The following examples shows how to associate a widget with a REST method and then have it rendered in the links
2700    * and aside section of the page:
2701    * 
2702    * <p class='bcode'>
2703    *    <ja>@RestMethod</ja>(
2704    *       widgets={
2705    *          MyWidget.<jk>class</jk>
2706    *       }
2707    *       htmldoc=<ja>@HtmlDoc</ja>(
2708    *          navlinks={
2709    *             <js>"$W{MyWidget}"</js>
2710    *          },
2711    *          aside={
2712    *             <js>"Check out this widget:  $W{MyWidget}"</js>
2713    *          }
2714    *       )
2715    *    )
2716    * </p>
2717    * 
2718    * <h5 class='section'>Notes:</h5>
2719    * <ul class='spaced-list'>
2720    *    <li>
2721    *       Widgets are inherited from super classes, but can be overridden by reusing the widget name.
2722    * </ul>
2723    * 
2724    * <h5 class='section'>See Also:</h5>
2725    * <ul>
2726    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Widgets">Overview &gt; juneau-rest-server &gt; Widgets</a>
2727    * </ul>
2728    */
2729   public static final String REST_widgets = PREFIX + "widgets.lo";
2730   
2731   
2732   //-------------------------------------------------------------------------------------------------------------------
2733   // Instance
2734   //-------------------------------------------------------------------------------------------------------------------
2735
2736   private final Object resource;
2737   final RestContextBuilder builder;
2738   private final boolean
2739      allowHeaderParams,
2740      allowBodyParam,
2741      renderResponseStackTraces,
2742      useStackTraceHashes;
2743   private final String
2744      defaultCharset,
2745      clientVersionHeader,
2746      contextPath;
2747   private final long
2748      maxInput;
2749   
2750   final String fullPath;
2751
2752   private final Map<String,Widget> widgets;
2753
2754   private final Set<String> allowedMethodParams;
2755
2756   private final RestContextProperties properties;
2757   private final Map<Class<?>,RestParam> paramResolvers;
2758   private final SerializerGroup serializers;
2759   private final ParserGroup parsers;
2760   private final HttpPartSerializer partSerializer;
2761   private final HttpPartParser partParser;
2762   private final EncoderGroup encoders;
2763   private final List<MediaType>
2764      consumes,
2765      produces;
2766   private final Map<String,Object> 
2767      defaultRequestHeaders,
2768      defaultResponseHeaders,
2769      staticFileResponseHeaders;
2770   private final BeanContext beanContext;
2771   private final RestConverter[] converters;
2772   private final RestGuard[] guards;
2773   private final ResponseHandler[] responseHandlers;
2774   private final MimetypesFileTypeMap mimetypesFileTypeMap;
2775   private final StaticFileMapping[] staticFiles;
2776   private final String[] staticFilesPaths;
2777   private final MessageBundle msgs;
2778   private final Config config;
2779   private final VarResolver varResolver;
2780   private final Map<String,RestCallRouter> callRouters;
2781   private final Map<String,RestJavaMethod> callMethods;
2782   private final Map<String,RestContext> childResources;
2783   private final RestLogger logger;
2784   private final RestCallHandler callHandler;
2785   private final RestInfoProvider infoProvider;
2786   private final RestException initException;
2787   private final RestContext parentContext;
2788   private final RestResourceResolver resourceResolver;
2789
2790   // Lifecycle methods
2791   private final Method[]
2792      postInitMethods,
2793      postInitChildFirstMethods,
2794      preCallMethods,
2795      postCallMethods,
2796      startCallMethods,
2797      endCallMethods,
2798      destroyMethods;
2799   private final RestParam[][]
2800      preCallMethodParams,
2801      postCallMethodParams;
2802   private final Class<?>[][]
2803      postInitMethodParams,
2804      postInitChildFirstMethodParams,
2805      startCallMethodParams,
2806      endCallMethodParams,
2807      destroyMethodParams;
2808
2809   // In-memory cache of images and stylesheets in the org.apache.juneau.rest.htdocs package.
2810   private final Map<String,StreamResource> staticFilesCache = new ConcurrentHashMap<>();
2811
2812   private final ClasspathResourceManager staticResourceManager;
2813   private final ConcurrentHashMap<Integer,AtomicInteger> stackTraceHashes = new ConcurrentHashMap<>();
2814
2815
2816   /**
2817    * Constructor.
2818    * 
2819    * @param builder The servlet configuration object.
2820    * @throws Exception If any initialization problems were encountered.
2821    */
2822   public RestContext(RestContextBuilder builder) throws Exception {
2823      super(builder.getPropertyStore());
2824      
2825      RestException _initException = null;
2826      
2827      try {
2828         ServletContext servletContext = builder.servletContext;
2829
2830         this.resource = builder.resource;
2831         this.builder = builder;
2832         this.parentContext = builder.parentContext;
2833         
2834         PropertyStore ps = getPropertyStore().builder().add(builder.properties).build();
2835         Class<?> resourceClass = resource.getClass();
2836
2837         contextPath = nullIfEmpty(getStringProperty(REST_contextPath, null));
2838         allowHeaderParams = getBooleanProperty(REST_allowHeaderParams, true);
2839         allowBodyParam = getBooleanProperty(REST_allowBodyParam, true);
2840         allowedMethodParams = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(StringUtils.split(getStringProperty(REST_allowedMethodParams, "HEAD,OPTIONS")))));
2841         renderResponseStackTraces = getBooleanProperty(REST_renderResponseStackTraces, false);
2842         useStackTraceHashes = getBooleanProperty(REST_useStackTraceHashes, true);
2843         defaultCharset = getStringProperty(REST_defaultCharset, "utf-8");
2844         maxInput = getLongProperty(REST_maxInput, 100_000_000l);
2845         clientVersionHeader = getStringProperty(REST_clientVersionHeader, "X-Client-Version");
2846
2847         converters = getInstanceArrayProperty(REST_converters, resource, RestConverter.class, new RestConverter[0], true, this);
2848         guards = getInstanceArrayProperty(REST_guards, resource, RestGuard.class, new RestGuard[0], true, this);
2849         responseHandlers = getInstanceArrayProperty(REST_responseHandlers, resource, ResponseHandler.class, new ResponseHandler[0], true, this);
2850
2851         Map<Class<?>,RestParam> _paramResolvers = new HashMap<>();
2852         for (RestParam rp : getInstanceArrayProperty(REST_paramResolvers, RestParam.class, new RestParam[0], true, this)) 
2853            _paramResolvers.put(rp.forClass(), rp);
2854         paramResolvers = unmodifiableMap(_paramResolvers);
2855         
2856         Map<String,Object> _defaultRequestHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
2857         _defaultRequestHeaders.putAll(getMapProperty(REST_defaultRequestHeaders, String.class));
2858         defaultRequestHeaders = unmodifiableMap(new LinkedHashMap<>(_defaultRequestHeaders));
2859         
2860         defaultResponseHeaders = getMapProperty(REST_defaultResponseHeaders, Object.class);
2861         staticFileResponseHeaders = getMapProperty(REST_staticFileResponseHeaders, Object.class); 
2862         
2863         logger = getInstanceProperty(REST_logger, resource, RestLogger.class, NoOpRestLogger.class, true, this);
2864
2865         varResolver = builder.varResolverBuilder
2866            .vars(
2867               FileVar.class, 
2868               LocalizationVar.class, 
2869               RequestAttributeVar.class, 
2870               RequestFormDataVar.class, 
2871               RequestHeaderVar.class, 
2872               RequestPathVar.class, 
2873               RequestQueryVar.class, 
2874               RequestVar.class,
2875               RestInfoVar.class,
2876               SerializedRequestAttrVar.class, 
2877               ServletInitParamVar.class, 
2878               UrlVar.class, 
2879               UrlEncodeVar.class, 
2880               WidgetVar.class
2881            )
2882            .build()
2883         ;
2884
2885         config = builder.config.resolving(this.varResolver.createSession());
2886         
2887         properties = builder.properties;
2888         serializers = SerializerGroup.create().append(getInstanceArrayProperty(REST_serializers, Serializer.class, new Serializer[0], true, resource, ps)).build();
2889         parsers = ParserGroup.create().append(getInstanceArrayProperty(REST_parsers, Parser.class, new Parser[0], true, resource, ps)).build();
2890         partSerializer = getInstanceProperty(REST_partSerializer, HttpPartSerializer.class, SimpleUonPartSerializer.class, true, resource, ps);
2891         partParser = getInstanceProperty(REST_partSerializer, HttpPartParser.class, UonPartParser.class, true, resource, ps);
2892         encoders = new EncoderGroupBuilder().append(getInstanceArrayProperty(REST_encoders, Encoder.class, new Encoder[0], true, resource, ps)).build();
2893         beanContext = BeanContext.create().apply(ps).build();
2894
2895         mimetypesFileTypeMap = new ExtendedMimetypesFileTypeMap();
2896         for (String mimeType : getArrayProperty(REST_mimeTypes, String.class))
2897            mimetypesFileTypeMap.addMimeTypes(mimeType);
2898         
2899         ClasspathResourceFinder rf = getInstanceProperty(REST_classpathResourceFinder, ClasspathResourceFinder.class, ClasspathResourceFinderBasic.class, true, this);
2900         boolean useClasspathResourceCaching = getProperty(REST_useClasspathResourceCaching, boolean.class, true);
2901         staticResourceManager = new ClasspathResourceManager(resourceClass, rf, useClasspathResourceCaching);
2902
2903         consumes = getListProperty(REST_consumes, MediaType.class, parsers.getSupportedMediaTypes());
2904         produces = getListProperty(REST_produces, MediaType.class, serializers.getSupportedMediaTypes());
2905         
2906         staticFiles = ArrayUtils.reverse(getArrayProperty(REST_staticFiles, StaticFileMapping.class));
2907         Set<String> s = new TreeSet<>();
2908         for (StaticFileMapping sfm : staticFiles)
2909            s.add(sfm.path);
2910         staticFilesPaths = s.toArray(new String[s.size()]);
2911         
2912         MessageBundleLocation[] mbl = getInstanceArrayProperty(REST_messages, MessageBundleLocation.class, new MessageBundleLocation[0]);
2913         if (mbl.length == 0)
2914            msgs = new MessageBundle(resourceClass, "");
2915         else {
2916            msgs = new MessageBundle(mbl[0] != null ? mbl[0].baseClass : resourceClass, mbl[0].bundlePath);
2917            for (int i = 1; i < mbl.length; i++)
2918               msgs.addSearchPath(mbl[i] != null ? mbl[i].baseClass : resourceClass, mbl[i].bundlePath);
2919         }
2920         
2921         fullPath = (builder.parentContext == null ? "" : (builder.parentContext.fullPath + '/')) + builder.path;
2922         
2923         this.childResources = Collections.synchronizedMap(new LinkedHashMap<String,RestContext>());  // Not unmodifiable on purpose so that children can be replaced.
2924         
2925         Map<String,Widget> _widgets = new LinkedHashMap<>();
2926         for (Widget w : getInstanceArrayProperty(REST_widgets, resource, Widget.class, new Widget[0], true, ps))
2927            _widgets.put(w.getName(), w);
2928         this.widgets = unmodifiableMap(_widgets);
2929
2930         //----------------------------------------------------------------------------------------------------
2931         // Initialize the child resources.
2932         // Done after initializing fields above since we pass this object to the child resources.
2933         //----------------------------------------------------------------------------------------------------
2934         List<String> methodsFound = new LinkedList<>();   // Temporary to help debug transient duplicate method issue.
2935         Map<String,RestCallRouter.Builder> routers = new LinkedHashMap<>();
2936         Map<String,RestJavaMethod> _javaRestMethods = new LinkedHashMap<>();
2937         Map<String,Method>
2938            _startCallMethods = new LinkedHashMap<>(),
2939            _preCallMethods = new LinkedHashMap<>(),
2940            _postCallMethods = new LinkedHashMap<>(),
2941            _endCallMethods = new LinkedHashMap<>(),
2942            _postInitMethods = new LinkedHashMap<>(),
2943            _postInitChildFirstMethods = new LinkedHashMap<>(),
2944            _destroyMethods = new LinkedHashMap<>();
2945         List<RestParam[]>
2946            _preCallMethodParams = new ArrayList<>(),
2947            _postCallMethodParams = new ArrayList<>();
2948         List<Class<?>[]>
2949            _startCallMethodParams = new ArrayList<>(),
2950            _endCallMethodParams = new ArrayList<>(),
2951            _postInitMethodParams = new ArrayList<>(),
2952            _postInitChildFirstMethodParams = new ArrayList<>(),
2953            _destroyMethodParams = new ArrayList<>();
2954
2955         for (java.lang.reflect.Method method : resourceClass.getMethods()) {
2956            if (method.isAnnotationPresent(RestMethod.class)) {
2957               RestMethod a = method.getAnnotation(RestMethod.class);
2958               methodsFound.add(method.getName() + "," + a.name() + "," + a.path());
2959               try {
2960                  if (! Modifier.isPublic(method.getModifiers()))
2961                     throw new RestServletException("@RestMethod method {0}.{1} must be defined as public.", resourceClass.getName(), method.getName());
2962
2963                  RestJavaMethod sm = new RestJavaMethod(resource, method, this);
2964                  String httpMethod = sm.getHttpMethod();
2965
2966                  // PROXY is a special case where a method returns an interface that we
2967                  // can perform REST calls against.
2968                  // We override the CallMethod.invoke() method to insert our logic.
2969                  if ("PROXY".equals(httpMethod)) {
2970
2971                     final ClassMeta<?> interfaceClass = beanContext.getClassMeta(method.getGenericReturnType());
2972                     final Map<String,Method> remoteableMethods = interfaceClass.getRemoteableMethods();
2973                     if (remoteableMethods.isEmpty())
2974                        throw new RestException(SC_INTERNAL_SERVER_ERROR, "Method {0} returns an interface {1} that doesn't define any remoteable methods.", getMethodSignature(method), interfaceClass.getReadableName());
2975
2976                     sm = new RestJavaMethod(resource, method, this) {
2977
2978                        @Override
2979                        int invoke(String pathInfo, RestRequest req, RestResponse res) throws RestException {
2980
2981                           int rc = super.invoke(pathInfo, req, res);
2982                           if (rc != SC_OK)
2983                              return rc;
2984
2985                           final Object o = res.getOutput();
2986
2987                           if ("GET".equals(req.getMethod())) {
2988                              res.setOutput(getMethodInfo(remoteableMethods.values()));
2989                              return SC_OK;
2990
2991                           } else if ("POST".equals(req.getMethod())) {
2992                              if (pathInfo.indexOf('/') != -1)
2993                                 pathInfo = pathInfo.substring(pathInfo.lastIndexOf('/')+1);
2994                              pathInfo = urlDecode(pathInfo);
2995                              java.lang.reflect.Method m = remoteableMethods.get(pathInfo);
2996                              if (m != null) {
2997                                 try {
2998                                    // Parse the args and invoke the method.
2999                                    Parser p = req.getBody().getParser();
3000                                    try (Closeable in = p.isReaderParser() ? req.getReader() : req.getInputStream()) {
3001                                       Object output = m.invoke(o, p.parseArgs(in, m.getGenericParameterTypes()));
3002                                       res.setOutput(output);
3003                                    }
3004                                    return SC_OK;
3005                                 } catch (Exception e) {
3006                                    throw new RestException(SC_INTERNAL_SERVER_ERROR, e);
3007                                 }
3008                              }
3009                           }
3010                           return SC_NOT_FOUND;
3011                        }
3012                     };
3013
3014                     _javaRestMethods.put(method.getName(), sm);
3015                     addToRouter(routers, "GET", sm);
3016                     addToRouter(routers, "POST", sm);
3017
3018                  } else {
3019                     _javaRestMethods.put(method.getName(), sm);
3020                     addToRouter(routers, httpMethod, sm);
3021                  }
3022               } catch (RestServletException e) {
3023                  throw new RestServletException("Problem occurred trying to serialize methods on class {0}, methods={1}", resourceClass.getName(), JsonSerializer.DEFAULT_LAX.serialize(methodsFound)).initCause(e);
3024               }
3025            }
3026         }
3027
3028         for (Method m : ClassUtils.getAllMethods(resourceClass, true)) {
3029            if (ClassUtils.isPublic(m) && m.isAnnotationPresent(RestHook.class)) {
3030               HookEvent he = m.getAnnotation(RestHook.class).value();
3031               String sig = ClassUtils.getMethodSignature(m);
3032               switch(he) {
3033                  case PRE_CALL: {
3034                     if (! _preCallMethods.containsKey(sig)) {
3035                        Visibility.setAccessible(m);
3036                        _preCallMethods.put(sig, m);
3037                        _preCallMethodParams.add(findParams(m, null, true));
3038                     }
3039                     break;
3040                  }
3041                  case POST_CALL: {
3042                     if (! _postCallMethods.containsKey(sig)) {
3043                        Visibility.setAccessible(m);
3044                        _postCallMethods.put(sig, m);
3045                        _postCallMethodParams.add(findParams(m, null, true));
3046                     }
3047                     break;
3048                  }
3049                  case START_CALL: {
3050                     if (! _startCallMethods.containsKey(sig)) {
3051                        Visibility.setAccessible(m);
3052                        _startCallMethods.put(sig, m);
3053                        _startCallMethodParams.add(m.getParameterTypes());
3054                        ClassUtils.assertArgsOfType(m, HttpServletRequest.class, HttpServletResponse.class);
3055                     }
3056                     break;
3057                  }
3058                  case END_CALL: {
3059                     if (! _endCallMethods.containsKey(sig)) {
3060                        Visibility.setAccessible(m);
3061                        _endCallMethods.put(sig, m);
3062                        _endCallMethodParams.add(m.getParameterTypes());
3063                        ClassUtils.assertArgsOfType(m, HttpServletRequest.class, HttpServletResponse.class);
3064                     }
3065                     break;
3066                  }
3067                  case POST_INIT: {
3068                     if (! _postInitMethods.containsKey(sig)) {
3069                        Visibility.setAccessible(m);
3070                        _postInitMethods.put(sig, m);
3071                        _postInitMethodParams.add(m.getParameterTypes());
3072                        ClassUtils.assertArgsOfType(m, RestContext.class);
3073                     }
3074                     break;
3075                  }
3076                  case POST_INIT_CHILD_FIRST: {
3077                     if (! _postInitChildFirstMethods.containsKey(sig)) {
3078                        Visibility.setAccessible(m);
3079                        _postInitChildFirstMethods.put(sig, m);
3080                        _postInitChildFirstMethodParams.add(m.getParameterTypes());
3081                        ClassUtils.assertArgsOfType(m, RestContext.class);
3082                     }
3083                     break;
3084                  }
3085                  case DESTROY: {
3086                     if (! _destroyMethods.containsKey(sig)) {
3087                        Visibility.setAccessible(m);
3088                        _destroyMethods.put(sig, m);
3089                        _destroyMethodParams.add(m.getParameterTypes());
3090                        ClassUtils.assertArgsOfType(m, RestContext.class);
3091                     }
3092                     break;
3093                  }
3094                  default: // Ignore INIT
3095               }
3096            }
3097         }
3098
3099         this.callMethods = unmodifiableMap(_javaRestMethods);
3100         this.preCallMethods = _preCallMethods.values().toArray(new Method[_preCallMethods.size()]);
3101         this.postCallMethods = _postCallMethods.values().toArray(new Method[_postCallMethods.size()]);
3102         this.startCallMethods = _startCallMethods.values().toArray(new Method[_startCallMethods.size()]);
3103         this.endCallMethods = _endCallMethods.values().toArray(new Method[_endCallMethods.size()]);
3104         this.postInitMethods = _postInitMethods.values().toArray(new Method[_postInitMethods.size()]);
3105         this.postInitChildFirstMethods = _postInitChildFirstMethods.values().toArray(new Method[_postInitChildFirstMethods.size()]);
3106         this.destroyMethods = _destroyMethods.values().toArray(new Method[_destroyMethods.size()]);
3107         this.preCallMethodParams = _preCallMethodParams.toArray(new RestParam[_preCallMethodParams.size()][]);
3108         this.postCallMethodParams = _postCallMethodParams.toArray(new RestParam[_postCallMethodParams.size()][]);
3109         this.startCallMethodParams = _startCallMethodParams.toArray(new Class[_startCallMethodParams.size()][]);
3110         this.endCallMethodParams = _endCallMethodParams.toArray(new Class[_endCallMethodParams.size()][]);
3111         this.postInitMethodParams = _postInitMethodParams.toArray(new Class[_postInitMethodParams.size()][]);
3112         this.postInitChildFirstMethodParams = _postInitChildFirstMethodParams.toArray(new Class[_postInitChildFirstMethodParams.size()][]);
3113         this.destroyMethodParams = _destroyMethodParams.toArray(new Class[_destroyMethodParams.size()][]);
3114
3115         Map<String,RestCallRouter> _callRouters = new LinkedHashMap<>();
3116         for (RestCallRouter.Builder crb : routers.values())
3117            _callRouters.put(crb.getHttpMethodName(), crb.build());
3118         this.callRouters = unmodifiableMap(_callRouters);
3119
3120         // Initialize our child resources.
3121         resourceResolver = getInstanceProperty(REST_resourceResolver, resource, RestResourceResolver.class, parentContext == null ? BasicRestResourceResolver.class : parentContext.resourceResolver, true, this);
3122         for (Object o : getArrayProperty(REST_children, Object.class)) {
3123            String path = null;
3124            Object r = null;
3125            if (o instanceof RestChild) {
3126               RestChild rc = (RestChild)o;
3127               path = rc.path;
3128               r = rc.resource;
3129            } else if (o instanceof Class<?>) {
3130               Class<?> c = (Class<?>)o;
3131               // Don't allow specifying yourself as a child.  Causes an infinite loop.
3132               if (c == builder.resourceClass)
3133                  continue;
3134               r = c;
3135            } else {
3136               r = o;
3137            }
3138
3139            RestContextBuilder childBuilder = null;
3140
3141            if (o instanceof Class) {
3142               Class<?> oc = (Class<?>)o;
3143               childBuilder = new RestContextBuilder(builder.inner, oc, this);
3144               r = resourceResolver.resolve(resource, oc, childBuilder);
3145            } else {
3146               r = o;
3147               childBuilder = new RestContextBuilder(builder.inner, o.getClass(), this);
3148            }
3149
3150            childBuilder.init(r);
3151            if (r instanceof RestServlet)
3152               ((RestServlet)r).innerInit(childBuilder);
3153            childBuilder.servletContext(servletContext);
3154            RestContext rc2 = new RestContext(childBuilder);
3155            if (r instanceof RestServlet)
3156               ((RestServlet)r).setContext(rc2);
3157            path = childBuilder.path;
3158            childResources.put(path, rc2);
3159         }
3160
3161         callHandler = getInstanceProperty(REST_callHandler, resource, RestCallHandler.class, BasicRestCallHandler.class, true, this);
3162         infoProvider = getInstanceProperty(REST_infoProvider, resource, RestInfoProvider.class, BasicRestInfoProvider.class, true, this);
3163
3164      } catch (RestException e) {
3165         _initException = e;
3166         throw e;
3167      } catch (Exception e) {
3168         _initException = new RestException(SC_INTERNAL_SERVER_ERROR, e);
3169         throw e;
3170      } finally {
3171         initException = _initException;
3172      }
3173   }
3174
3175   private static void addToRouter(Map<String, RestCallRouter.Builder> routers, String httpMethodName, RestJavaMethod cm) throws RestServletException {
3176      if (! routers.containsKey(httpMethodName))
3177         routers.put(httpMethodName, new RestCallRouter.Builder(httpMethodName));
3178      routers.get(httpMethodName).add(cm);
3179   }
3180
3181   /**
3182    * Returns the resource resolver associated with this context.
3183    * 
3184    * <p>
3185    * The resource resolver is used for instantiating child resource classes.
3186    * 
3187    * <h5 class='section'>See Also:</h5>
3188    * <ul>
3189    *    <li class='jf'>{@link #REST_resourceResolver}
3190    * </ul>
3191    * 
3192    * @return The resource resolver associated with this context.
3193    */
3194   protected RestResourceResolver getResourceResolver() {
3195      return resourceResolver;
3196   }
3197
3198   /**
3199    * Returns the variable resolver for this servlet.
3200    * 
3201    * <p>
3202    * Variable resolvers are used to replace variables in property values.
3203    * They can be nested arbitrarily deep.
3204    * They can also return values that themselves contain other variables.
3205    * 
3206    * <h5 class='figure'>Example:</h5>
3207    * <p class='bcode'>
3208    *    <ja>@RestResource</ja>(
3209    *       messages=<js>"nls/Messages"</js>,
3210    *       properties={
3211    *          <ja>@Property</ja>(name=<js>"title"</js>,value=<js>"$L{title}"</js>),  <jc>// Localized variable in Messages.properties</jc>
3212    *          <ja>@Property</ja>(name=<js>"javaVendor"</js>,value=<js>"$S{java.vendor,Oracle}"</js>),  <jc>// System property with default value</jc>
3213    *          <ja>@Property</ja>(name=<js>"foo"</js>,value=<js>"bar"</js>),
3214    *          <ja>@Property</ja>(name=<js>"bar"</js>,value=<js>"baz"</js>),
3215    *          <ja>@Property</ja>(name=<js>"v1"</js>,value=<js>"$R{foo}"</js>),  <jc>// Request variable.  value="bar"</jc>
3216    *          <ja>@Property</ja>(name=<js>"v1"</js>,value=<js>"$R{foo,bar}"</js>),  <jc>// Request variable.  value="bar"</jc>
3217    *       }
3218    *    )
3219    *    <jk>public class</jk> MyRestResource <jk>extends</jk> BasicRestServlet {
3220    * </p>
3221    * 
3222    * <p>
3223    * A typical usage pattern involves using variables inside the {@link HtmlDoc @HtmlDoc} annotation:
3224    * <p class='bcode'>
3225    *    <ja>@RestMethod</ja>(
3226    *       name=<jsf>GET</jsf>, path=<js>"/{name}/*"</js>,
3227    *       htmldoc=@HtmlDoc(
3228    *          navlinks={
3229    *             <js>"up: $R{requestParentURI}"</js>,
3230    *             <js>"options: servlet:/?method=OPTIONS"</js>,
3231    *             <js>"editLevel: servlet:/editLevel?logger=$A{attribute.name, OFF}"</js>
3232    *          }
3233    *          header={
3234    *             <js>"&lt;h1&gt;$L{MyLocalizedPageTitle}&lt;/h1&gt;"</js>
3235    *          },
3236    *          aside={
3237    *             <js>"$F{resources/AsideText.html}"</js>
3238    *          }
3239    *       )
3240    *    )
3241    *    <jk>public</jk> LoggerEntry getLogger(RestRequest req, <ja>@Path</ja> String name) <jk>throws</jk> Exception {
3242    * </p>
3243    * 
3244    * <h5 class='section'>See Also:</h5>
3245    * <ul>
3246    *    <li class='jm'>{@link org.apache.juneau.rest.RestContextBuilder#vars(Class...)} - For adding custom vars.
3247    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.SvlVariables">Overview &gt; juneau-rest-server &gt; SVL Variables</a>
3248    *    <li class='link'><a class="doclink" href="../../../../overview-summary.html#DefaultRestSvlVariables">Overview &gt; juneau-rest-server &gt; Default REST SVL Variables</a>
3249    * </ul>
3250    * 
3251    * @return The var resolver in use by this resource.
3252    */
3253   public VarResolver getVarResolver() {
3254      return varResolver;
3255   }
3256
3257   /**
3258    * Returns the config file associated with this servlet.
3259    * 
3260    * <p>
3261    * The config file is identified via one of the following:
3262    * <ul>
3263    *    <li class='ja'>{@link RestResource#config()}
3264    *    <li class='jm'>{@link RestContextBuilder#config(Config)}
3265    * </ul>
3266    * 
3267    * @return 
3268    *    The resolving config file associated with this servlet.  
3269    *    <br>Never <jk>null</jk>.
3270    */
3271   public Config getConfig() {
3272      return config;
3273   }
3274
3275   /**
3276    * Resolve a static resource file.
3277    * 
3278    * <p>
3279    * The location of static resources are defined via:
3280    * <ul>
3281    *    <li class='jf'>{@link RestContext#REST_staticFiles RestContext.REST_staticFiles}
3282    * </ul>
3283    * 
3284    * @param pathInfo The unencoded path info.
3285    * @return The resource, or <jk>null</jk> if the resource could not be resolved.
3286    * @throws IOException
3287    */
3288   public StreamResource resolveStaticFile(String pathInfo) throws IOException {
3289      if (! staticFilesCache.containsKey(pathInfo)) {
3290         String p = urlDecode(trimSlashes(pathInfo));
3291         if (p.indexOf("..") != -1)
3292            throw new RestException(SC_NOT_FOUND, "Invalid path");
3293         for (StaticFileMapping sfm : staticFiles) {
3294            String path = sfm.path;
3295            if (p.startsWith(path)) {
3296               String remainder = (p.equals(path) ? "" : p.substring(path.length()));
3297               if (remainder.isEmpty() || remainder.startsWith("/")) {
3298                  String p2 = sfm.location + remainder;
3299                  try (InputStream is = getClasspathResource(sfm.resourceClass, p2, null)) {
3300                     if (is != null) {
3301                        int i = p2.lastIndexOf('/');
3302                        String name = (i == -1 ? p2 : p2.substring(i+1));
3303                        String mediaType = mimetypesFileTypeMap.getContentType(name);
3304                        Map<String,Object> responseHeaders = sfm.responseHeaders != null ? sfm.responseHeaders : staticFileResponseHeaders;
3305                        staticFilesCache.put(pathInfo, new StreamResource(MediaType.forString(mediaType), responseHeaders, is));
3306                        return staticFilesCache.get(pathInfo);
3307                     }
3308                  }
3309               }
3310            }
3311         }
3312      }
3313      return staticFilesCache.get(pathInfo);
3314   }
3315
3316   /**
3317    * Same as {@link Class#getResourceAsStream(String)} except if it doesn't find the resource on this class, searches
3318    * up the parent hierarchy chain.
3319    * 
3320    * <p>
3321    * If the resource cannot be found in the classpath, then an attempt is made to look in the JVM working directory.
3322    * 
3323    * <p>
3324    * If the <code>locale</code> is specified, then we look for resources whose name matches that locale.
3325    * <br>For example, if looking for the resource <js>"MyResource.txt"</js> for the Japanese locale, we will look for
3326    * files in the following order:
3327    * <ol>
3328    *    <li><js>"MyResource_ja_JP.txt"</js>
3329    *    <li><js>"MyResource_ja.txt"</js>
3330    *    <li><js>"MyResource.txt"</js>
3331    * </ol>
3332    * 
3333    * <h5 class='section'>Example:</h5>
3334    * <p class='bcode'>
3335    *    <jc>// A rest method that (unsafely!) returns the contents of a localized file </jc>
3336    * <jc>// from the classpath.</jc>
3337    *    <ja>@RestMethod</ja>(path=<js>"/foo"</js>)
3338    *    <jk>public</jk> Object myMethod(RestRequest req, <ja>@Query</ja>(<js>"file"</js>) String file) {
3339    *       <jk>return</jk> getContext().getClasspathResource(file, req.getLocale());
3340    *    }
3341    * </p>
3342    * 
3343    * <h5 class='section'>See Also:</h5>
3344    * <ul>
3345    *    <li class='jf'>{@link #REST_classpathResourceFinder}
3346    * </ul>
3347    * 
3348    * @param name The resource name.
3349    * @param locale 
3350    *    Optional locale.
3351    *    <br>If <jk>null</jk>, won't look for localized file names.
3352    * @return An input stream of the resource, or <jk>null</jk> if the resource could not be found.
3353    * @throws IOException
3354    */
3355   public InputStream getClasspathResource(String name, Locale locale) throws IOException {
3356      return staticResourceManager.getStream(name, locale);
3357   }
3358
3359   /**
3360    * Same as {@link #getClasspathResource(String, Locale)}, but allows you to override the class used for looking
3361    * up the classpath resource.
3362    * 
3363    * <h5 class='section'>Example:</h5>
3364    * <p class='bcode'>
3365    *    <jc>// A rest method that (unsafely!) returns the contents of a localized file </jc>
3366    * <jc>// from the classpath.</jc>
3367    *    <ja>@RestMethod</ja>(path=<js>"/foo"</js>)
3368    *    <jk>public</jk> Object myMethod(RestRequest req, <ja>@Query</ja>(<js>"file"</js>) String file) {
3369    *       <jk>return</jk> getContext().getClasspathResource(SomeOtherClass.<jk>class</jk>, file, req.getLocale());
3370    *    }
3371    * </p>
3372    * 
3373    * <h5 class='section'>See Also:</h5>
3374    * <ul>
3375    *    <li class='jf'>{@link #REST_classpathResourceFinder}
3376    * </ul>
3377    * 
3378    * @param baseClass 
3379    *    Overrides the default class to use for retrieving the classpath resource. 
3380    *    <br>If <jk>null</jk>, uses the REST resource class.
3381    * @param name The resource name.
3382    * @param locale 
3383    *    Optional locale.
3384    *    <br>If <jk>null</jk>, won't look for localized file names.
3385    * @return An input stream of the resource, or <jk>null</jk> if the resource could not be found.
3386    * @throws IOException
3387    */
3388   public InputStream getClasspathResource(Class<?> baseClass, String name, Locale locale) throws IOException {
3389      return staticResourceManager.getStream(baseClass, name, locale);
3390   }
3391
3392   /**
3393    * Reads the input stream from {@link #getClasspathResource(String, Locale)} into a String.
3394    * 
3395    * <h5 class='section'>Example:</h5>
3396    * <p class='bcode'>
3397    *    <jc>// A rest method that (unsafely!) returns the contents of a localized file </jc>
3398    * <jc>// from the classpath.</jc>
3399    *    <ja>@RestMethod</ja>(path=<js>"/foo"</js>)
3400    *    <jk>public</jk> String myMethod(RestRequest req, <ja>@Query</ja>(<js>"file"</js>) String file) {
3401    *       <jk>return</jk> getContext().getClasspathResourceAsString(file, req.getLocale());
3402    *    }
3403    * </p>
3404    * 
3405    * <h5 class='section'>See Also:</h5>
3406    * <ul>
3407    *    <li class='jf'>{@link #REST_classpathResourceFinder}
3408    * </ul>
3409    * 
3410    * @param name The resource name.
3411    * @param locale 
3412    *    Optional locale.
3413    *    <br>If <jk>null</jk>, won't look for localized file names.
3414    * @return The contents of the stream as a string, or <jk>null</jk> if the resource could not be found.
3415    * @throws IOException If resource could not be found.
3416    */
3417   public String getClasspathResourceAsString(String name, Locale locale) throws IOException {
3418      return staticResourceManager.getString(name, locale);
3419   }
3420
3421   /**
3422    * Same as {@link #getClasspathResourceAsString(String, Locale)}, but allows you to override the class used for looking
3423    * up the classpath resource.
3424    * 
3425    * <h5 class='section'>Example:</h5>
3426    * <p class='bcode'>
3427    *    <jc>// A rest method that (unsafely!) returns the contents of a localized file </jc>
3428    * <jc>// from the classpath.</jc>
3429    *    <ja>@RestMethod</ja>(path=<js>"/foo"</js>)
3430    *    <jk>public</jk> String myMethod(RestRequest req, <ja>@Query</ja>(<js>"file"</js>) String file) {
3431    *       <jk>return</jk> getContext().getClasspathResourceAsString(SomeOtherClass.<jk>class</jk>, file, req.getLocale());
3432    *    }
3433    * </p>
3434    * 
3435    * <h5 class='section'>See Also:</h5>
3436    * <ul>
3437    *    <li class='jf'>{@link #REST_classpathResourceFinder}
3438    * </ul>
3439    * 
3440    * @param baseClass 
3441    *    Overrides the default class to use for retrieving the classpath resource. 
3442    *    <br>If <jk>null</jk>, uses the REST resource class.
3443    * @param name The resource name.
3444    * @param locale 
3445    *    Optional locale.
3446    *    <br>If <jk>null</jk>, won't look for localized file names.
3447    * @return The contents of the stream as a string, or <jk>null</jk> if the resource could not be found.
3448    * @throws IOException If resource could not be found.
3449    */
3450   public String getClasspathResourceAsString(Class<?> baseClass, String name, Locale locale) throws IOException {
3451      return staticResourceManager.getString(baseClass, name, locale);
3452   }
3453   
3454   /**
3455    * Reads the input stream from {@link #getClasspathResource(String, Locale)} and parses it into a POJO using the parser
3456    * matched by the specified media type.
3457    * 
3458    * <p>
3459    * Useful if you want to load predefined POJOs from JSON files in your classpath.
3460    * 
3461    * <h5 class='section'>Example:</h5>
3462    * <p class='bcode'>
3463    *    <jc>// A rest method that (unsafely!) returns the contents of a localized file </jc>
3464    * <jc>// from the classpath parsed as an array of beans.</jc>
3465    *    <ja>@RestMethod</ja>(path=<js>"/foo"</js>)
3466    *    <jk>public</jk> MyBean[] myMethod(RestRequest req, <ja>@Query</ja>(<js>"file"</js>) String file) {
3467    *       <jk>return</jk> getContext().getClasspathResource(MyBean[].<jk>class</jk>, <jsf>JSON</jsf>, file, req.getLocale());
3468    *    }
3469    * </p>
3470    * 
3471    * <h5 class='section'>See Also:</h5>
3472    * <ul>
3473    *    <li class='jf'>{@link #REST_classpathResourceFinder}
3474    * </ul>
3475    * 
3476    * @param c The class type of the POJO to create.
3477    * @param mediaType The media type of the data in the stream (e.g. <js>"text/json"</js>)
3478    * @param name The resource name (e.g. "htdocs/styles.css").
3479    * @param locale 
3480    *    Optional locale.
3481    *    <br>If <jk>null</jk>, won't look for localized file names.
3482    * @return The parsed resource, or <jk>null</jk> if the resource could not be found.
3483    * @throws IOException
3484    * @throws ServletException If the media type was unknown or the input could not be parsed into a POJO.
3485    */
3486   public <T> T getClasspathResource(Class<T> c, MediaType mediaType, String name, Locale locale) throws IOException, ServletException {
3487      return getClasspathResource(null, c, mediaType, name, locale);
3488   }
3489
3490   /**
3491    * Same as {@link #getClasspathResource(Class, MediaType, String, Locale)}, except overrides the class used
3492    * for retrieving the classpath resource.
3493    * 
3494    * <h5 class='section'>See Also:</h5>
3495    * <ul>
3496    *    <li class='jf'>{@link #REST_classpathResourceFinder}
3497    * </ul>
3498    * 
3499    * <h5 class='section'>Example:</h5>
3500    * <p class='bcode'>
3501    *    <jc>// A rest method that (unsafely!) returns the contents of a localized file </jc>
3502    * <jc>// from the classpath parsed as an array of beans.</jc>
3503    *    <ja>@RestMethod</ja>(path=<js>"/foo"</js>)
3504    *    <jk>public</jk> MyBean[] myMethod(RestRequest req, <ja>@Query</ja>(<js>"file"</js>) String file) {
3505    *       <jk>return</jk> getContext().getClasspathResource(SomeOtherClass.<jk>class</jk>, MyBean[].<jk>class</jk>, <jsf>JSON</jsf>, file, req.getLocale());
3506    *    }
3507    * </p>
3508    * 
3509    * @param baseClass 
3510    *    Overrides the default class to use for retrieving the classpath resource. 
3511    *    <br>If <jk>null<jk>, uses the REST resource class.
3512    * @param c The class type of the POJO to create.
3513    * @param mediaType The media type of the data in the stream (e.g. <js>"text/json"</js>)
3514    * @param name The resource name (e.g. "htdocs/styles.css").
3515    * @param locale 
3516    *    Optional locale.
3517    *    <br>If <jk>null</jk>, won't look for localized file names.
3518    * @return The parsed resource, or <jk>null</jk> if the resource could not be found.
3519    * @throws IOException
3520    * @throws ServletException If the media type was unknown or the input could not be parsed into a POJO.
3521    */
3522   public <T> T getClasspathResource(Class<?> baseClass, Class<T> c, MediaType mediaType, String name, Locale locale) throws IOException, ServletException {
3523      InputStream is = getClasspathResource(baseClass, name, locale);
3524      if (is == null)
3525         return null;
3526      try {
3527         Parser p = parsers.getParser(mediaType);
3528         if (p != null) {
3529            try {
3530               try (Closeable in = p.isReaderParser() ? new InputStreamReader(is, UTF8) : is) {
3531                  return p.parse(in, c);
3532               }
3533            } catch (ParseException e) {
3534               throw new ServletException("Could not parse resource '' as media type '"+mediaType+"'.");
3535            }
3536         }
3537         throw new ServletException("Unknown media type '"+mediaType+"'");
3538      } catch (Exception e) {
3539         throw new ServletException("Could not parse resource with name '"+name+"'", e);
3540      }
3541   }
3542
3543   /**
3544    * Returns the path for this resource as defined by the {@link RestResource#path() @RestResource.path()} annotation or
3545    * {@link RestContextBuilder#path(String)} method concatenated with those on all parent classes.
3546    * 
3547    * <p>
3548    * If path is not specified, returns <js>"/"</js>.
3549    * <br>Path always starts with <js>"/"</js>.
3550    * 
3551    * <h5 class='section'>See Also:</h5>
3552    * <ul>
3553    *    <li class='jf'>{@link #REST_path}
3554    * </ul>
3555    * 
3556    * @return The servlet path.
3557    */
3558   public String getPath() {
3559      return fullPath;
3560   }
3561
3562   /**
3563    * The widgets used for resolving <js>"$W{...}"<js> variables.
3564    * 
3565    * <h5 class='section'>See Also:</h5>
3566    * <ul>
3567    *    <li class='jf'>{@link #REST_widgets}
3568    * </ul>
3569    * 
3570    * @return The var resolver widgets as a map with keys being the name returned by {@link Widget#getName()}.
3571    */
3572   public Map<String,Widget> getWidgets() {
3573      return widgets;
3574   }
3575
3576   /**
3577    * Returns the logger to use for this resource.
3578    * 
3579    * <h5 class='section'>See Also:</h5>
3580    * <ul>
3581    *    <li class='jf'>{@link #REST_logger}
3582    * </ul>
3583    * 
3584    * @return 
3585    *    The logger to use for this resource.  
3586    *    <br>Never <jk>null</jk>.
3587    */
3588   public RestLogger getLogger() {
3589      return logger;
3590   }
3591
3592   /**
3593    * Returns the resource bundle used by this resource.
3594    * 
3595    * <h5 class='section'>See Also:</h5>
3596    * <ul>
3597    *    <li class='jf'>{@link #REST_messages}
3598    * </ul>
3599    * 
3600    * @return 
3601    *    The resource bundle for this resource.  
3602    *    <br>Never <jk>null</jk>.
3603    */
3604   public MessageBundle getMessages() {
3605      return msgs;
3606   }
3607
3608   /**
3609    * Returns the REST information provider used by this resource.
3610    * 
3611    * <h5 class='section'>See Also:</h5>
3612    * <ul>
3613    *    <li class='jf'>{@link RestContext#REST_infoProvider}
3614    * </ul>
3615    * 
3616    * @return 
3617    *    The information provider for this resource.  
3618    *    <br>Never <jk>null</jk>.
3619    */
3620   public RestInfoProvider getInfoProvider() {
3621      return infoProvider;
3622   }
3623
3624   /**
3625    * Returns the REST call handler used by this resource.
3626    * 
3627    * <h5 class='section'>See Also:</h5>
3628    * <ul>
3629    *    <li class='jf'>{@link RestContext#REST_callHandler}
3630    * </ul>
3631    * 
3632    * @return 
3633    *    The call handler for this resource.  
3634    *    <br>Never <jk>null</jk>.
3635    */
3636   protected RestCallHandler getCallHandler() {
3637      return callHandler;
3638   }
3639
3640   /**
3641    * Returns a map of HTTP method names to call routers.
3642    * 
3643    * @return A map with HTTP method names upper-cased as the keys, and call routers as the values.
3644    */
3645   protected Map<String,RestCallRouter> getCallRouters() {
3646      return callRouters;
3647   }
3648
3649   /**
3650    * Returns the resource object.
3651    * 
3652    * <p>
3653    * This is the instance of the class annotated with the {@link RestResource @RestResource} annotation, usually
3654    * an instance of {@link RestServlet}.
3655    * 
3656    * @return 
3657    *    The resource object.  
3658    *    <br>Never <jk>null</jk>.
3659    */
3660   public Object getResource() {
3661      return resource;
3662   }
3663
3664   /**
3665    * Returns the resource object as a {@link RestServlet}.
3666    * 
3667    * @return
3668    *    The resource object cast to {@link RestServlet}, or <jk>null</jk> if the resource doesn't subclass from
3669    *    {@link RestServlet}.
3670    */
3671   public RestServlet getRestServlet() {
3672      return resource instanceof RestServlet ? (RestServlet)resource : null;
3673   }
3674
3675   /**
3676    * Throws a {@link RestException} if an exception occurred in the constructor of this object.
3677    * 
3678    * @throws RestException The initialization exception wrapped in a {@link RestException}.
3679    */
3680   protected void checkForInitException() throws RestException {
3681      if (initException != null)
3682         throw initException;
3683   }
3684
3685   /**
3686    * Returns the parent resource context (if this resource was initialized from a parent).
3687    * 
3688    * <p>
3689    * From this object, you can get access to the parent resource class itself using {@link #getResource()} or
3690    * {@link #getRestServlet()}
3691    * 
3692    * @return The parent resource context, or <jk>null</jk> if there is no parent context.
3693    */
3694   public RestContext getParentContext() {
3695      return parentContext;
3696   }
3697
3698   /**
3699    * Returns the {@link BeanContext} object used for parsing path variables and header values.
3700    * 
3701    * @return The bean context used for parsing path variables and header values.
3702    */
3703   public BeanContext getBeanContext() {
3704      return beanContext;
3705   }
3706
3707   /**
3708    * Returns the class-level properties associated with this servlet.
3709    * 
3710    * <p>
3711    * Properties at the class level are defined via the following:
3712    * <ul>
3713    *    <li class='ja'>{@link RestResource#properties()}
3714    *    <li class='jm'>{@link RestContextBuilder#set(String, Object)}
3715    *    <li class='jm'>{@link RestContextBuilder#set(Map)}
3716    * </ul>
3717    * 
3718    * <h5 class='section'>Notes:</h5>
3719    * <ul class='spaced-list'>
3720    *    <li>
3721    *       The returned {@code Map} is mutable.  
3722    *       <br>Therefore, subclasses are free to override or set additional initialization parameters in their {@code init()} method.
3723    * </ul>
3724    * 
3725    * @return The resource properties as a {@link RestContextProperties}.
3726    */
3727   public RestContextProperties getProperties() {
3728      return properties;
3729   }
3730
3731   /**
3732    * Returns the serializers registered with this resource.
3733    * 
3734    * <h5 class='section'>See Also:</h5>
3735    * <ul>
3736    *    <li class='jf'>{@link RestContext#REST_serializers}
3737    * </ul>
3738    * 
3739    * @return The serializers registered with this resource.
3740    */
3741   public SerializerGroup getSerializers() {
3742      return serializers;
3743   }
3744
3745   /**
3746    * Returns the parsers registered with this resource.
3747    * 
3748    * <p>
3749    * Parsers at the class level are defined via the following:
3750    * <ul>
3751    *    <li class='jf'>{@link RestContext#REST_parsers}
3752    * </ul>
3753    * 
3754    * @return The parsers registered with this resource.
3755    */
3756   public ParserGroup getParsers() {
3757      return parsers;
3758   }
3759
3760   /**
3761    * Returns the servlet init parameter returned by {@link ServletConfig#getInitParameter(String)}.
3762    * 
3763    * @param name The init parameter name.
3764    * @return The servlet init parameter, or <jk>null</jk> if not found.
3765    */
3766   public String getServletInitParameter(String name) {
3767      return builder.getInitParameter(name);
3768   }
3769
3770   /**
3771    * Returns the child resources associated with this servlet.
3772    * 
3773    * @return
3774    *    An unmodifiable map of child resources.
3775    *    Keys are the {@link RestResource#path() @RestResource.path()} annotation defined on the child resource.
3776    */
3777   public Map<String,RestContext> getChildResources() {
3778      return Collections.unmodifiableMap(childResources);
3779   }
3780
3781   /**
3782    * Returns the number of times this exception was thrown based on a hash of its stacktrace.
3783    * 
3784    * <h5 class='section'>See Also:</h5>
3785    * <ul>
3786    *    <li class='jf'>{@link RestContext#REST_useStackTraceHashes}
3787    * </ul>
3788    * 
3789    * @param e The exception to check.
3790    * @return
3791    *    The number of times this exception was thrown, or <code>0</code> if {@link #REST_useStackTraceHashes}
3792    *    setting is not enabled.
3793    */
3794   public int getStackTraceOccurrence(Throwable e) {
3795      if (! useStackTraceHashes)
3796         return 0;
3797      int h = e.hashCode();
3798      stackTraceHashes.putIfAbsent(h, new AtomicInteger());
3799      return stackTraceHashes.get(h).incrementAndGet();
3800   }
3801
3802   /**
3803    * Returns whether it's safe to render stack traces in HTTP responses.
3804    * 
3805    * <h5 class='section'>See Also:</h5>
3806    * <ul>
3807    *    <li class='jf'>{@link RestContext#REST_useStackTraceHashes}
3808    * </ul>
3809    * 
3810    * @return <jk>true</jk> if setting is enabled.
3811    */
3812   public boolean isRenderResponseStackTraces() {
3813      return renderResponseStackTraces;
3814   }
3815
3816   /**
3817    * Returns whether it's safe to pass header values in as GET parameters.
3818    * 
3819    * <h5 class='section'>See Also:</h5>
3820    * <ul>
3821    *    <li class='jf'>{@link RestContext#REST_allowHeaderParams}
3822    * </ul>
3823    * 
3824    * @return <jk>true</jk> if setting is enabled.
3825    */
3826   public boolean isAllowHeaderParams() {
3827      return allowHeaderParams;
3828   }
3829
3830   /**
3831    * Returns whether it's safe to pass the HTTP body as a <js>"body"</js> GET parameter.
3832    * 
3833    * <h5 class='section'>See Also:</h5>
3834    * <ul>
3835    *    <li class='jf'>{@link RestContext#REST_allowBodyParam}
3836    * </ul>
3837    * 
3838    * @return <jk>true</jk> if setting is enabled.
3839    */
3840   public boolean isAllowBodyParam() {
3841      return allowBodyParam;
3842   }
3843
3844   /**
3845    * Returns the default charset to use on requests and responses when not specified on the request.
3846    * 
3847    * <h5 class='section'>See Also:</h5>
3848    * <ul>
3849    *    <li class='jf'>{@link RestContext#REST_defaultCharset}
3850    * </ul>
3851    * 
3852    * @return 
3853    *    The default charset.
3854    *    <br>Never <jk>null</jk>.
3855    */
3856   public String getDefaultCharset() {
3857      return defaultCharset;
3858   }
3859
3860   /**
3861    * Returns the maximum request input size in bytes.
3862    * 
3863    * <h5 class='section'>See Also:</h5>
3864    * <ul>
3865    *    <li class='jf'>{@link RestContext#REST_maxInput}
3866    * </ul>
3867    * 
3868    * @return The maximum request input size in bytes.
3869    */
3870   public long getMaxInput() {
3871      return maxInput;
3872   }
3873
3874   /**
3875    * Returns the name of the client version header name used by this resource.
3876    * 
3877    * <h5 class='section'>See Also:</h5>
3878    * <ul>
3879    *    <li class='jf'>{@link RestContext#REST_clientVersionHeader}
3880    * </ul>
3881    * 
3882    * @return 
3883    *    The name of the client version header used by this resource.  
3884    *    <br>Never <jk>null</jk>.
3885    */
3886   public String getClientVersionHeader() {
3887      return clientVersionHeader;
3888   }
3889
3890   /**
3891    * Returns <jk>true</jk> if the specified <code>Method</code> GET parameter value can be used to override
3892    * the method name in the HTTP header.
3893    * 
3894    * <h5 class='section'>See Also:</h5>
3895    * <ul>
3896    *    <li class='jf'>{@link RestContext#REST_allowedMethodParams}
3897    * </ul>
3898    * 
3899    * @param m The method name, upper-cased.
3900    * @return <jk>true</jk> if this resource allows the specified method to be overridden.
3901    */
3902   public boolean allowMethodParam(String m) {
3903      return (! isEmpty(m) && (allowedMethodParams.contains(m) || allowedMethodParams.contains("*")));
3904   }
3905
3906   /**
3907    * Returns the HTTP-part parser associated with this resource.
3908    * 
3909    * <h5 class='section'>See Also:</h5>
3910    * <ul>
3911    *    <li class='jf'>{@link RestContext#REST_partParser}
3912    * </ul>
3913    * 
3914    * @return 
3915    *    The HTTP-part parser associated with this resource.  
3916    *    <br>Never <jk>null</jk>.
3917    */
3918   public HttpPartParser getPartParser() {
3919      return partParser;
3920   }
3921
3922   /**
3923    * Returns the HTTP-part serializer associated with this resource.
3924    * 
3925    * <h5 class='section'>See Also:</h5>
3926    * <ul>
3927    *    <li class='jf'>{@link RestContext#REST_partSerializer}
3928    * </ul>
3929    * 
3930    * @return 
3931    *    The HTTP-part serializer associated with this resource.  
3932    *    <br>Never <jk>null</jk>.
3933    */
3934   public HttpPartSerializer getPartSerializer() {
3935      return partSerializer;
3936   }
3937
3938   /**
3939    * Returns the encoders associated with this resource.
3940    * 
3941    * <h5 class='section'>See Also:</h5>
3942    * <ul>
3943    *    <li class='jf'>{@link RestContext#REST_encoders}
3944    * </ul>
3945    * 
3946    * @return 
3947    *    The encoders associated with this resource.  
3948    *    <br>Never <jk>null</jk>.
3949    */
3950   public EncoderGroup getEncoders() {
3951      return encoders;
3952   }
3953
3954   /**
3955    * Returns the explicit list of supported accept types for this resource.
3956    * 
3957    * <h5 class='section'>See Also:</h5>
3958    * <ul>
3959    *    <li class='jf'>{@link RestContext#REST_serializers}
3960    *    <li class='jf'>{@link RestContext#REST_produces}
3961    * </ul>
3962    * 
3963    * @return 
3964    *    The supported <code>Accept</code> header values for this resource.  
3965    *    <br>Never <jk>null</jk>.
3966    */
3967   public List<MediaType> getProduces() {
3968      return produces;
3969   }
3970
3971   /**
3972    * Returns the explicit list of supported content types for this resource.
3973    * 
3974    * <h5 class='section'>See Also:</h5>
3975    * <ul>
3976    *    <li class='jf'>{@link RestContext#REST_parsers}
3977    *    <li class='jf'>{@link RestContext#REST_consumes}
3978    * </ul>
3979    * 
3980    * @return 
3981    *    The supported <code>Content-Type</code> header values for this resource.  
3982    *    <br>Never <jk>null</jk>.
3983    */
3984   public List<MediaType> getConsumes() {
3985      return consumes;
3986   }
3987
3988   /**
3989    * Returns the default request headers for this resource.
3990    * 
3991    * <h5 class='section'>See Also:</h5>
3992    * <ul>
3993    *    <li class='jf'>{@link RestContext#REST_defaultRequestHeaders}
3994    * </ul>
3995    * 
3996    * @return 
3997    *    The default request headers for this resource.  
3998    *    <br>Never <jk>null</jk>.
3999    */
4000   public Map<String,Object> getDefaultRequestHeaders() {
4001      return defaultRequestHeaders;
4002   }
4003
4004   /**
4005    * Returns the default response headers for this resource.
4006    * 
4007    * <h5 class='section'>See Also:</h5>
4008    * <ul>
4009    *    <li class='jf'>{@link RestContext#REST_defaultResponseHeaders}
4010    * </ul>
4011    * 
4012    * @return 
4013    *    The default response headers for this resource.  
4014    *    <br>Never <jk>null</jk>.
4015    */
4016   public Map<String,Object> getDefaultResponseHeaders() {
4017      return defaultResponseHeaders;
4018   }
4019
4020   /**
4021    * Returns the converters associated with this resource at the class level.
4022    * 
4023    * <h5 class='section'>See Also:</h5>
4024    * <ul>
4025    *    <li class='jf'>{@link RestContext#REST_converters}
4026    * </ul>
4027    * 
4028    * @return 
4029    *    The converters associated with this resource.  
4030    *    <br>Never <jk>null</jk>.
4031    */
4032   public RestConverter[] getConverters() {
4033      return converters;
4034   }
4035
4036   /**
4037    * Returns the guards associated with this resource at the class level.
4038    * 
4039    * <h5 class='section'>See Also:</h5>
4040    * <ul>
4041    *    <li class='jf'>{@link RestContext#REST_guards}
4042    * </ul>
4043    * 
4044    * @return 
4045    *    The guards associated with this resource.  
4046    *    <br>Never <jk>null</jk>.
4047    */
4048   public RestGuard[] getGuards() {
4049      return guards;
4050   }
4051
4052   /**
4053    * Returns the response handlers associated with this resource.
4054    * 
4055    * <h5 class='section'>See Also:</h5>
4056    * <ul>
4057    *    <li class='jf'>{@link RestContext#REST_responseHandlers}
4058    * </ul>
4059    * 
4060    * @return 
4061    *    The response handlers associated with this resource.  
4062    *    <br>Never <jk>null</jk>.
4063    */
4064   protected ResponseHandler[] getResponseHandlers() {
4065      return responseHandlers;
4066   }
4067
4068   /**
4069    * Returns <jk>true</jk> if this resource has any child resources associated with it.
4070    * 
4071    * <h5 class='section'>See Also:</h5>
4072    * <ul>
4073    *    <li class='jf'>{@link RestContext#REST_children}
4074    * </ul>
4075    * 
4076    * @return <jk>true</jk> if this resource has any child resources associated with it.
4077    */
4078   public boolean hasChildResources() {
4079      return ! childResources.isEmpty();
4080   }
4081
4082   /**
4083    * Returns the context of the child resource associated with the specified path.
4084    * 
4085    * <h5 class='section'>See Also:</h5>
4086    * <ul>
4087    *    <li class='jf'>{@link RestContext#REST_children}
4088    * </ul>
4089    * 
4090    * @param path The path of the child resource to resolve.
4091    * @return The resolved context, or <jk>null</jk> if it could not be resolved.
4092    */
4093   public RestContext getChildResource(String path) {
4094      return childResources.get(path);
4095   }
4096
4097   /**
4098    * Returns the context path of the resource.
4099    * 
4100    * <h5 class='section'>See Also:</h5>
4101    * <ul>
4102    *    <li class='jf'>{@link RestContext#REST_contextPath}
4103    * </ul>
4104    * 
4105    * @return 
4106    *    The context path of this resource.
4107    *    <br>If not specified, returns the context path of the ascendant resource.
4108    */
4109   public String getContextPath() {
4110      if (contextPath != null)
4111         return contextPath;
4112      if (parentContext != null)
4113         return parentContext.getContextPath();
4114      return null;
4115   }
4116
4117   /**
4118    * Returns the parameters defined on the specified Java method.
4119    * 
4120    * @param method The Java method to check.
4121    * @return The parameters defined on the Java method.
4122    */
4123   public RestParam[] getRestParams(Method method) {
4124      return callMethods.get(method.getName()).params;
4125   }
4126
4127   /**
4128    * Returns the media type for the specified file name.
4129    * 
4130    * <h5 class='section'>See Also:</h5>
4131    * <ul>
4132    *    <li class='jf'>{@link RestContext#REST_mimeTypes}
4133    * </ul>
4134    * 
4135    * @param name The file name.
4136    * @return The MIME-type, or <jk>null</jk> if it could not be determined.
4137    */
4138   public String getMediaTypeForName(String name) {
4139      return mimetypesFileTypeMap.getContentType(name);
4140   }
4141
4142   /**
4143    * Returns <jk>true</jk> if the specified path refers to a static file.
4144    * 
4145    * <p>
4146    * Static files are files pulled from the classpath and served up directly to the browser.
4147    * 
4148    * <h5 class='section'>See Also:</h5>
4149    * <ul>
4150    *    <li class='jf'>{@link RestContext#REST_staticFiles}
4151    * </ul>
4152    * 
4153    * @param p The URL path remainder after the servlet match.
4154    * @return <jk>true</jk> if the specified path refers to a static file.
4155    */
4156   public boolean isStaticFile(String p) {
4157      return pathStartsWith(p, staticFilesPaths);
4158   }
4159
4160   /**
4161    * Returns the REST Java methods defined in this resource.
4162    * 
4163    * <p>
4164    * These are the methods annotated with the {@link RestMethod @RestMethod} annotation.
4165    * 
4166    * @return 
4167    *    An unmodifiable map of Java method names to call method objects.
4168    */
4169   public Map<String,RestJavaMethod> getCallMethods() {
4170      return callMethods;
4171   }
4172
4173   /**
4174    * Finds the {@link RestParam} instances to handle resolving objects on the calls to the specified Java method.
4175    * 
4176    * @param method The Java method being called.
4177    * @param pathPattern The parsed URL path pattern.
4178    * @param isPreOrPost Whether this is a {@link HookEvent#PRE_CALL} or {@link HookEvent#POST_CALL}.
4179    * @return The array of resolvers.
4180    * @throws ServletException If an annotation usage error was detected.
4181    */
4182   protected RestParam[] findParams(Method method, UrlPathPattern pathPattern, boolean isPreOrPost) throws ServletException {
4183
4184      Type[] pt = method.getGenericParameterTypes();
4185      Annotation[][] pa = method.getParameterAnnotations();
4186      RestParam[] rp = new RestParam[pt.length];
4187      int attrIndex = 0;
4188      PropertyStore ps = getPropertyStore();
4189
4190      for (int i = 0; i < pt.length; i++) {
4191
4192         Type t = pt[i];
4193         if (t instanceof Class) {
4194            Class<?> c = (Class<?>)t;
4195            rp[i] = paramResolvers.get(c);
4196            if (rp[i] == null)
4197               rp[i] = RestParamDefaults.STANDARD_RESOLVERS.get(c);
4198         }
4199
4200         for (Annotation a : pa[i]) {
4201            if (a instanceof Header)
4202               rp[i] = new RestParamDefaults.HeaderObject((Header)a, t, ps);
4203            else if (a instanceof FormData)
4204               rp[i] = new RestParamDefaults.FormDataObject(method, (FormData)a, t, ps);
4205            else if (a instanceof Query)
4206               rp[i] = new RestParamDefaults.QueryObject(method, (Query)a, t, ps);
4207            else if (a instanceof HasFormData)
4208               rp[i] = new RestParamDefaults.HasFormDataObject(method, (HasFormData)a, t);
4209            else if (a instanceof HasQuery)
4210               rp[i] = new RestParamDefaults.HasQueryObject(method, (HasQuery)a, t);
4211            else if (a instanceof Body)
4212               rp[i] = new RestParamDefaults.BodyObject(t);
4213            else if (a instanceof org.apache.juneau.rest.annotation.Method)
4214               rp[i] = new RestParamDefaults.MethodObject(method, t);
4215            else if (a instanceof PathRemainder)
4216               rp[i] = new RestParamDefaults.PathRemainderObject(method, t);
4217         }
4218
4219         if (rp[i] == null) {
4220
4221            if (isPreOrPost)
4222               throw new RestServletException("Invalid parameter specified for method ''{0}'' at index position {1}", method, i);
4223
4224            Path p = null;
4225            for (Annotation a : pa[i])
4226               if (a instanceof Path)
4227                  p = (Path)a;
4228
4229            String name = (p == null ? "" : firstNonEmpty(p.name(), p.value()));
4230
4231            if (isEmpty(name)) {
4232               int idx = attrIndex++;
4233               String[] vars = pathPattern.getVars();
4234               if (vars.length <= idx)
4235                  throw new RestServletException("Number of attribute parameters in method ''{0}'' exceeds the number of URL pattern variables.", method);
4236
4237               // Check for {#} variables.
4238               String idxs = String.valueOf(idx);
4239               for (int j = 0; j < vars.length; j++)
4240                  if (isNumeric(vars[j]) && vars[j].equals(idxs))
4241                     name = vars[j];
4242
4243               if (isEmpty(name))
4244                  name = pathPattern.getVars()[idx];
4245            }
4246            rp[i] = new RestParamDefaults.PathParameterObject(name, t);
4247         }
4248      }
4249
4250      return rp;
4251   }
4252
4253   /*
4254    * Calls all @RestHook(PRE) methods.
4255    */
4256   void preCall(RestRequest req, RestResponse res) throws RestException {
4257      for (int i = 0; i < preCallMethods.length; i++)
4258         preOrPost(resource, preCallMethods[i], preCallMethodParams[i], req, res);
4259   }
4260
4261   /*
4262    * Calls all @RestHook(POST) methods.
4263    */
4264   void postCall(RestRequest req, RestResponse res) throws RestException {
4265      for (int i = 0; i < postCallMethods.length; i++)
4266         preOrPost(resource, postCallMethods[i], postCallMethodParams[i], req, res);
4267   }
4268
4269   private static void preOrPost(Object resource, Method m, RestParam[] mp, RestRequest req, RestResponse res) throws RestException {
4270      if (m != null) {
4271         Object[] args = new Object[mp.length];
4272         for (int i = 0; i < mp.length; i++) {
4273            try {
4274               args[i] = mp[i].resolve(req, res);
4275            } catch (RestException e) {
4276               throw e;
4277            } catch (Exception e) {
4278               throw new RestException(SC_BAD_REQUEST,
4279                  "Invalid data conversion.  Could not convert {0} ''{1}'' to type ''{2}'' on method ''{3}.{4}''.",
4280                  mp[i].getParamType().name(), mp[i].getName(), mp[i].getType(), m.getDeclaringClass().getName(), m.getName()
4281               ).initCause(e);
4282            }
4283         }
4284         try {
4285            m.invoke(resource, args);
4286         } catch (RestException e) {
4287            throw e;
4288         } catch (Exception e) {
4289            throw new RestException(SC_INTERNAL_SERVER_ERROR, e.getLocalizedMessage()).initCause(e);
4290         }
4291      }
4292   }
4293
4294   /*
4295    * Calls all @RestHook(START) methods.
4296    */
4297   void startCall(HttpServletRequest req, HttpServletResponse res) {
4298      for (int i = 0; i < startCallMethods.length; i++)
4299         startOrFinish(resource, startCallMethods[i], startCallMethodParams[i], req, res);
4300   }
4301
4302   /*
4303    * Calls all @RestHook(FINISH) methods.
4304    */
4305   void finishCall(HttpServletRequest req, HttpServletResponse res) {
4306      for (int i = 0; i < endCallMethods.length; i++)
4307         startOrFinish(resource, endCallMethods[i], endCallMethodParams[i], req, res);
4308   }
4309
4310   private static void startOrFinish(Object resource, Method m, Class<?>[] p, HttpServletRequest req, HttpServletResponse res) {
4311      if (m != null) {
4312         Object[] args = new Object[p.length];
4313         for (int i = 0; i < p.length; i++) {
4314            if (p[i] == HttpServletRequest.class)
4315               args[i] = req;
4316            else if (p[i] == HttpServletResponse.class)
4317               args[i] = res;
4318         }
4319         try {
4320            m.invoke(resource, args);
4321         } catch (RestException e) {
4322            throw e;
4323         } catch (Exception e) {
4324            throw new RestException(SC_INTERNAL_SERVER_ERROR, e.getLocalizedMessage()).initCause(e);
4325         }
4326      }
4327   }
4328
4329   /*
4330    * Calls all @RestHook(POST_INIT) methods.
4331    */
4332   void postInit() throws ServletException {
4333      for (int i = 0; i < postInitMethods.length; i++)
4334         postInitOrDestroy(resource, postInitMethods[i], postInitMethodParams[i]);
4335      for (RestContext childContext : this.childResources.values())
4336         childContext.postInit();
4337   }
4338
4339   /*
4340    * Calls all @RestHook(POST_INIT_CHILD_FIRST) methods.
4341    */
4342   void postInitChildFirst() throws ServletException {
4343      for (RestContext childContext : this.childResources.values())
4344         childContext.postInitChildFirst();
4345      for (int i = 0; i < postInitChildFirstMethods.length; i++)
4346         postInitOrDestroy(resource, postInitChildFirstMethods[i], postInitChildFirstMethodParams[i]);
4347   }
4348
4349   private void postInitOrDestroy(Object r, Method m, Class<?>[] p) {
4350      if (m != null) {
4351         Object[] args = new Object[p.length];
4352         for (int i = 0; i < p.length; i++) {
4353            if (p[i] == RestContext.class)
4354               args[i] = this;
4355            else if (p[i] == RestContextBuilder.class)
4356               args[i] = this.builder;
4357            else if (p[i] == ServletConfig.class)
4358               args[i] = this.builder.inner;
4359         }
4360         try {
4361            m.invoke(r, args);
4362         } catch (RestException e) {
4363            throw e;
4364         } catch (Exception e) {
4365            throw new RestException(SC_INTERNAL_SERVER_ERROR, e.getLocalizedMessage()).initCause(e);
4366         }
4367      }
4368   }
4369
4370   /**
4371    * Calls {@link Servlet#destroy()} on any child resources defined on this resource.
4372    */
4373   protected void destroy() {
4374      for (int i = 0; i < destroyMethods.length; i++) {
4375         try {
4376            postInitOrDestroy(resource, destroyMethods[i], destroyMethodParams[i]);
4377         } catch (Exception e) {
4378            e.printStackTrace();
4379         }
4380      }
4381
4382      for (RestContext r : childResources.values()) {
4383         r.destroy();
4384         if (r.resource instanceof Servlet)
4385            ((Servlet)r.resource).destroy();
4386      }
4387   }
4388
4389   /**
4390    * Unused.
4391    */
4392   @Override /* BeanContextBuilder */
4393   public BeanSession createSession(BeanSessionArgs args) {
4394      throw new NoSuchMethodError();
4395   }
4396
4397   /**
4398    * Unused.
4399    */
4400   @Override /* BeanContextBuilder */
4401   public BeanSessionArgs createDefaultSessionArgs() {
4402      throw new NoSuchMethodError();
4403   }
4404}