Author: buildbot
Date: Thu Nov 29 16:48:18 2012
New Revision: 840012
Log:
Production update by buildbot for cxf
Modified:
websites/production/cxf/content/cache/docs.pageCache
websites/production/cxf/content/docs/jax-rs-basics.html
Modified: websites/production/cxf/content/cache/docs.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/cxf/content/docs/jax-rs-basics.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-basics.html (original)
+++ websites/production/cxf/content/docs/jax-rs-basics.html Thu Nov 29 16:48:18
2012
@@ -722,6 +722,152 @@ Note that JAXRS MessageBodyWriter and Me
<p>Note that by the time a custom ResourceComparator is called the provided
resource classes or methods have already been successfully matched by the
runtime.</p>
+<p>For example, the optional HTTP request and URI parameters (query, matrix,
headers, cookies) and form parameters do not affect the selection algorithm.<br
clear="none">
+A custom ResourceComparator can be used when this limitation is considered to
be problematic. For example, the following shows one such implementation:</p>
+
+<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
+<pre class="code-java">
+
+<span class="code-keyword">public</span> class QueryResourceInfoComperator
<span class="code-keyword">extends</span> OperationResourceInfoComparator <span
class="code-keyword">implements</span>
+ ResourceComparator {
+
+ <span class="code-keyword">public</span> QueryResourceInfoComperator() {
+ <span class="code-keyword">super</span>(<span
class="code-keyword">null</span>, <span class="code-keyword">null</span>);
+ }
+
+ @Override
+ <span class="code-keyword">public</span> <span
class="code-object">int</span> compare(ClassResourceInfo cri1,
ClassResourceInfo cri2, Message message) {
+ <span class="code-comment">// Leave <span
class="code-object">Class</span> selection to CXF
+</span> <span class="code-keyword">return</span> 0;
+ }
+
+ @Override
+ <span class="code-keyword">public</span> <span
class="code-object">int</span> compare(OperationResourceInfo oper1,
OperationResourceInfo oper2, Message message) {
+
+ <span class="code-comment">// Check <span
class="code-keyword">if</span> CXF can make a decision
+</span> <span class="code-object">int</span> cxfResult = <span
class="code-keyword">super</span>.compare(oper1, oper2);
+ <span class="code-keyword">if</span> (cxfResult != 0)
+ <span class="code-keyword">return</span> cxfResult;
+
+ <span class="code-comment">// Compare QueryParam annotations
+</span> Set<<span class="code-object">String</span>> qParams =
getParams((<span class="code-object">String</span>)
message.get(Message.QUERY_STRING));
+ <span class="code-object">int</span> op1Counter =
getMatchingRate(getAnnotations(oper1.getMethodToInvoke().getParameterAnnotations()),
+ qParams);
+ <span class="code-object">int</span> op2Counter =
getMatchingRate(getAnnotations(oper2.getMethodToInvoke().getParameterAnnotations()),
+ qParams);
+
+ <span class="code-keyword">return</span> op1Counter == op2Counter
+ ? 0
+ : op1Counter< op2Counter
+ ? 1
+ : -1;
+ }
+
+ /**
+ * This method calculates a number indicating a good or bad match between
+ * queryParams from request and annotated method parameters. A higher
number
+ * means a better match.
+ *
+ * @param annotations
+ * Map contains name of QueryParam method parameters as a key
and
+ * a <span class="code-object">Boolean</span> value indicating
an existing <span class="code-keyword">default</span> value <span
class="code-keyword">for</span> <span class="code-keyword">this</span>
+ * parameter.
+ * @param queryParams
+ * A Set of query parameters provided within the request
+ * @<span class="code-keyword">return</span> A positive or negative
number, indicating a good match between
+ * query and method
+ */
+ <span class="code-keyword">protected</span> <span
class="code-object">int</span> getMatchingRate(Map<<span
class="code-object">String</span>, <span class="code-object">Boolean</span>>
annotations, Set<<span class="code-object">String</span>> queryParams) {
+ <span class="code-object">int</span> rate = 0;
+ <span class="code-keyword">for</span> (<span
class="code-object">String</span> anno : annotations.keySet()) {
+ <span class="code-keyword">if</span> (queryParams.contains(anno))
{
+ <span class="code-comment">// URL query matches one method
parameter
+</span> rate += 2;
+ } <span class="code-keyword">else</span> <span
class="code-keyword">if</span> (!annotations.get(anno).booleanValue()) {
+ <span class="code-comment">// No <span
class="code-keyword">default</span> value exists <span
class="code-keyword">for</span> method parameter
+</span> rate -= 1;
+ }
+ }
+ <span class="code-keyword">return</span> rate;
+ }
+
+ /**
+ * @param opParamAnnos
+ * Array containing all annotations <span
class="code-keyword">for</span> all method parameters
+ * @<span class="code-keyword">return</span> Key in Map is QueryParam
name, and Value indicates <span class="code-keyword">if</span> a <span
class="code-keyword">default</span>
+ * value is present.
+ */
+ <span class="code-keyword">protected</span> Map<<span
class="code-object">String</span>, <span class="code-object">Boolean</span>>
getAnnotations(Annotation[][] opParamAnnos) {
+ Map<<span class="code-object">String</span>, <span
class="code-object">Boolean</span>> parameterAnnos = <span
class="code-keyword">new</span> HashMap<<span
class="code-object">String</span>, <span
class="code-object">Boolean</span>>();
+
+ <span class="code-keyword">if</span> (opParamAnnos.length == 0)
+ <span class="code-keyword">return</span> parameterAnnos;
+
+ <span class="code-keyword">for</span> (Annotation[] pAnnos :
opParamAnnos) {
+ QueryParam qParam = <span class="code-keyword">null</span>;
+ DefaultValue dValue = <span class="code-keyword">null</span>;
+ <span class="code-keyword">for</span> (Annotation anno : pAnnos) {
+ <span class="code-keyword">if</span> (anno <span
class="code-keyword">instanceof</span> QueryParam)
+ qParam = (QueryParam) anno;
+ <span class="code-keyword">if</span> (anno <span
class="code-keyword">instanceof</span> DefaultValue)
+ dValue = (DefaultValue) anno;
+ }
+ parameterAnnos.put(qParam.value(), <span
class="code-object">Boolean</span>.valueOf((dValue != <span
class="code-keyword">null</span>)));
+ }
+
+ <span class="code-keyword">return</span> parameterAnnos;
+ }
+
+ /**
+ * @param query
+ * URL Query
+ * @<span class="code-keyword">return</span> A Set of all keys, contained
within query.
+ */
+ <span class="code-keyword">protected</span> Set<<span
class="code-object">String</span>> getParams(<span
class="code-object">String</span> query) {
+ Set<<span class="code-object">String</span>> params = <span
class="code-keyword">new</span> HashSet<<span
class="code-object">String</span>>();
+ <span class="code-keyword">if</span> (query == <span
class="code-keyword">null</span> || query.length() == 0)
+ <span class="code-keyword">return</span> params;
+
+ <span class="code-keyword">try</span> {
+ <span class="code-keyword">for</span> (<span
class="code-object">String</span> param : query.split(<span
class="code-quote">"&"</span>)) {
+ <span class="code-object">String</span> pair[] =
param.split(<span class="code-quote">"="</span>);
+ <span class="code-object">String</span> key =
URLDecoder.decode(pair[0], <span class="code-quote">"UTF-8"</span>);
+ params.add(key);
+ }
+ } <span class="code-keyword">catch</span>
(UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ <span class="code-keyword">return</span> params;
+ }
+}
+
+</pre>
+</div></div>
+
+<p>Now consider this code:</p>
+
+<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
+<pre class="code-java">
+@Path(<span class="code-quote">"/paramTest"</span>)
+<span class="code-keyword">public</span> class MySimpleService {
+
+ @GET
+ <span class="code-keyword">public</span> <span
class="code-object">String</span> getFoo(@QueryParam(<span
class="code-quote">"foo"</span>) <span class="code-object">String</span> foo){
+ <span class="code-keyword">return</span> <span
class="code-quote">"foo:"</span> + foo;
+ }
+
+ @GET
+ <span class="code-keyword">public</span> <span
class="code-object">String</span> getFooBar(@QueryParam(<span
class="code-quote">"foo"</span>) <span class="code-object">String</span> foo,
+@QueryParam(<span class="code-quote">"bar"</span>) <span
class="code-object">String</span> bar){
+ <span class="code-keyword">return</span> <span
class="code-quote">"foo:"</span> + foo + <span class="code-quote">"
bar:"</span> + bar;
+ }
+
+
+}
+</pre>
+</div></div>
+
+<p>Using the custom comparator will lead to getFoo() method accepting a single
query parameter selected when a request URI has only one query parameter, and
getFoo() method accepting multiple query parameters selected when a request URI
has at least two query parameters. Further customizations can be made to get
the parameter values affecting the selection process too. </p>
<h1><a shape="rect" name="JAX-RSBasics-Contextannotations"></a>Context
annotations</h1>