Author: buildbot
Date: Wed Apr  4 15:56:43 2018
New Revision: 1027845

Log:
Production update by buildbot for cxf

Modified:
    websites/production/cxf/content/cache/docs.pageCache
    websites/production/cxf/content/docs/jax-rs-search.html

Modified: websites/production/cxf/content/cache/docs.pageCache
==============================================================================
Binary files - no diff available.

Modified: websites/production/cxf/content/docs/jax-rs-search.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-search.html (original)
+++ websites/production/cxf/content/docs/jax-rs-search.html Wed Apr  4 15:56:43 
2018
@@ -32,8 +32,8 @@
 <link type="text/css" rel="stylesheet" 
href="/resources/highlighter/styles/shThemeCXF.css">
 
 <script src='/resources/highlighter/scripts/shCore.js'></script>
-<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
 <script src='/resources/highlighter/scripts/shBrushJava.js'></script>
+<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
 <script>
   SyntaxHighlighter.defaults['toolbar'] = false;
   SyntaxHighlighter.all();
@@ -118,11 +118,11 @@ Apache CXF -- JAX-RS Search
            <!-- Content -->
            <div class="wiki-content">
 <div id="ConfluenceContent"><h1 id="JAX-RSSearch-JAX-RSSearch">JAX-RS 
Search</h1><p>&#160;</p><p><style type="text/css">/*<![CDATA[*/
-div.rbtoc1508777326031 {padding: 0px;}
-div.rbtoc1508777326031 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1508777326031 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1522857365130 {padding: 0px;}
+div.rbtoc1522857365130 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1522857365130 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></p><div class="toc-macro rbtoc1508777326031">
+/*]]>*/</style></p><div class="toc-macro rbtoc1522857365130">
 <ul class="toc-indentation"><li><a shape="rect" 
href="#JAX-RSSearch-JAX-RSSearch">JAX-RS Search</a>
 <ul class="toc-indentation"><li><a shape="rect" 
href="#JAX-RSSearch-AdvancedSearchQueries">Advanced Search 
Queries</a></li><li><a shape="rect" 
href="#JAX-RSSearch-SupportedQueryLanguages">Supported Query Languages</a>
 <ul class="toc-indentation"><li><a shape="rect" 
href="#JAX-RSSearch-FeedItemQueryLanguage">Feed Item Query 
Language</a></li><li><a shape="rect" href="#JAX-RSSearch-OpenDataProtocol">Open 
Data Protocol</a></li></ul>
@@ -163,42 +163,42 @@ div.rbtoc1508777326031 li {margin-left:
 
 </pre>
 </div></div><p>Note that no "_s" or "_search" query parameter is available, 
the whole query string starting after "?" represents an actual FIQL 
expression.<br clear="none"> Please use "search.use.all.query.component" 
contextual property for this option be supported.</p><p>Alternatively the 
expressions can be encoded as URI path segments, see the sections below for 
more information.</p><h3 id="JAX-RSSearch-OpenDataProtocol">Open Data 
Protocol</h3><p>CXF 3.0.0-milestone2 supports the <a shape="rect" 
class="external-link" 
href="http://docs.oasis-open.org/odata/odata/v4.0/cos01/part2-url-conventions/odata-v4.0-cos01-part2-url-conventions.html#_Toc372793792";
 rel="nofollow">$filter</a> query defined as part of <a shape="rect" 
class="external-link" href="http://www.odata.org/"; rel="nofollow">Open Data 
Protocol</a>, courtesy of <a shape="rect" class="external-link" 
href="http://olingo.incubator.apache.org/";>Apache Olingo</a>.</p><p>The $filter 
query can have a number of the logical operator
 s, here is a summary of the operators supported in scope of Search 
API:</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Operator</p></th><th 
colspan="1" rowspan="1" 
class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>"eq"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Equal</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"ne"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Not Equal</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"lt"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Less Than</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"le"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Less or Equal</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>"gt"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Greater Than<
 /p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"ge"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Greater or Equal</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>"and"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>AND</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"or"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>OR</p></td></tr></tbody></table></div><p>&#160;</p><p>Please
 see the specification text for <a shape="rect" class="external-link" 
href="http://docs.oasis-open.org/odata/odata/v4.0/cos01/part2-url-conventions/odata-v4.0-cos01-part2-url-conventions.html#_Toc372793804";
 rel="nofollow">some examples</a>.</p><p>Please note that OData protocol is not 
supported by CXF Search API, only the $filter query is supported (only logical 
operators for now) for querying the application data with CXF Search API. Users 
should work directly with <a shape="rect" class="external-link" href
 ="http://olingo.incubator.apache.org/";>Apache Olingo</a> to get the <a 
shape="rect" class="external-link" href="http://www.odata.org/"; 
rel="nofollow">OData</a> protocol supported as part of the application 
flow.</p><p>Some of the following examples on this page may often refer to FIQL 
due to the fact FIQL has been supported for a long time, but the same examples 
will work with OData $filter expressions. For example, replace the 
"_s=name==CXF" query with "$filter=name eq CXF".</p><h2 
id="JAX-RSSearch-Whentouseadvancedqueries.">When to use advanced 
queries.</h2><p>Consider a typical query expression such as 
"a=avalue&amp;c=cvalue". This can mean either "find all resources with 'a' and 
'c' properties equal to 'avalue' and 'cvalue'" or "find all resources with 'a' 
or 'c' properties equal to 'avalue' and 'cvalue'". It is application specific 
on whether it is "and" or "or" as far as the combination of multiple query 
properties is concerned.</p><p>It is also to capture conditional expressi
 ons with the custom language, example, "find all resource with 'a' property 
less than 123" when a number of properties is large or the entities which can 
be searched are created dynamically.</p><p>Use FIQL or OData for capturing 
simple or medium complexity queries, typically in cases where a set of 
properties that a user can specify is well-known. Example, a book store 
resource will let users search books given a number of useful properties(those 
of Book and/or Library a given book is available in, etc).</p><p>Furthermore, 
consider using FIQL/OData and SearchConditionVisitor for the purpose of 
generalizing the search code, when the number of properties and entities is 
large, dynamic, etc.</p><h2 
id="JAX-RSSearch-DependenciesandConfiguration">Dependencies and 
Configuration</h2><p>The following dependency is required starting from CXF 
2.6.0:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">   &lt;dependency&gt;
-      &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
-      &lt;artifactId&gt;cxf-rt-rs-extension-search&lt;/artifactId&gt;
-      &lt;version&gt;2.6.0&lt;/version&gt;
-   &lt;/dependency&gt;
-
-   &lt;!-- If working with OData --&gt;
-   &lt;!--
-       &lt;dependency&gt;
-            &lt;groupId&gt;org.apache.olingo&lt;/groupId&gt;
-            &lt;artifactId&gt;olingo-odata2-core-incubating&lt;/artifactId&gt;
-            &lt;version&gt;1.1.0&lt;/version&gt; 
-        &lt;/dependency&gt;
-   --&gt;
-&#160;</pre>
-</div></div><p>Additionally, starting from CXF 2.6.0, <a shape="rect" 
class="external-link" 
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextProvider.java";>SearchContextProvider</a>
 needs to be registered as jaxrs:provider.</p><h2 
id="JAX-RSSearch-Workingwiththequeries">Working with the queries</h2><p><a 
shape="rect" class="external-link" 
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java";>SearchContext</a>
 needs be injected into an application code and used to retrieve a <a 
shape="rect" class="external-link" 
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java";>SearchCondition</a>
 representing the current FIQL/OData query. This SearchCondition can be used in 
a number of ways for finding the matching data.</p><p>In this section we as
 sume that the data to be matched are already available in memory. The 
follow-up section on converting the queries will show how the queries can be 
converted to some other query language typed or text expression.</p><p>So, 
suppose a list or map of Book instances is available. Here is one possible 
approach:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;dependency&gt;
+    &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
+    &lt;artifactId&gt;cxf-rt-rs-extension-search&lt;/artifactId&gt;
+    &lt;version&gt;2.6.0&lt;/version&gt;
+&lt;/dependency&gt;
+
+&lt;!-- If working with OData --&gt;
+&lt;!--
+&lt;dependency&gt;
+    &lt;groupId&gt;org.apache.olingo&lt;/groupId&gt;
+    &lt;artifactId&gt;olingo-odata2-core-incubating&lt;/artifactId&gt;
+    &lt;version&gt;1.1.0&lt;/version&gt; 
+&lt;/dependency&gt;
+--&gt;
+</pre>
+</div></div><p>Additionally, starting from CXF 2.6.0, <a shape="rect" 
class="external-link" 
href="https://github.com/apache/cxf/blob/master/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContextProvider.java";
 rel="nofollow">SearchContextProvider</a> needs to be registered as 
jaxrs:provider.</p><h2 id="JAX-RSSearch-Workingwiththequeries">Working with the 
queries</h2><p><a shape="rect" class="external-link" 
href="https://github.com/apache/cxf/blob/master/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchContext.java";
 rel="nofollow">SearchContext</a> needs be injected into an application code 
and used to retrieve a <a shape="rect" class="external-link" 
href="https://github.com/apache/cxf/blob/master/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java";
 rel="nofollow">SearchCondition</a> representing the current FIQL/OData query. 
This SearchCondition can be used in a number of ways for finding t
 he matching data.</p><p>In this section we assume that the data to be matched 
are already available in memory. The follow-up section on converting the 
queries will show how the queries can be converted to some other query language 
typed or text expression.</p><p>So, suppose a list or map of Book instances is 
available. Here is one possible approach:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@Path("books")
 public class Books {
 
-private Map&lt;Long, Book&gt; books;
-@Context
-private SearchContext context;
-
- @GET
- public List&lt;Book&gt; getBook() {
-
-   SearchCondition&lt;Book&gt; sc = searchContext.getCondition(Book.class);
-   // SearchCondition#isMet method can also be used to build a list of 
matching beans
-
-   // iterate over all the values in the books map and return a collection of 
matching beans
-   List&lt;Book&gt; found = sc.findAll(books.values());
-   return found;
- }
+    private Map&lt;Long, Book&gt; books;
+    @Context
+    private SearchContext context;
+
+    @GET
+    public List&lt;Book&gt; getBook() {
+
+        SearchCondition&lt;Book&gt; sc = 
searchContext.getCondition(Book.class);
+        // SearchCondition#isMet method can also be used to build a list of 
matching beans
+
+        // iterate over all the values in the books map and return a 
collection of matching beans
+        List&lt;Book&gt; found = sc.findAll(books.values());
+        return found;
+    }
 }
 </pre>
-</div></div><p>Note that a searchContext.getCondition(Book.class) call may 
return an arbitrary complex SearchCondition, it can be a simple primitive<br 
clear="none"> expression or a more complex, composite one.</p><h2 
id="JAX-RSSearch-Capturingthequeries">Capturing the queries</h2><p>For the 
query expression to be captured, a bean like Book.class is instantiated and has 
all the search properties injected into it. A complex composite expression will 
be 'injected' into a number of Book instances - something that may have to be 
optimized.</p><p>Note that by default, a bean such as Book class needs to have 
a matching property per every property name found in the FIQL expression, for 
example, given a 'name==b;id==123' expression, the Book class would need to 
have 'name' and 'id' properties available. The reason for this strict mode 
being enabled by default is that ignoring a property which can not be captured 
may lead to a false or unexpected match, for example, if Book 'name' property h
 as been renamed to 'title' then ignoring the 'name' property will lead to a 
wider match. Thus, if the property does not exist, 
org.apache.cxf.jaxrs.ext.search.PropertyNotFoundException will be thrown; 
capturing it can let returning an empty response or retry with the more lax 
mode, see the next paragraph.</p><p>When a more lax parsing of FIQL expressions 
is expected, for example, where the primitive expressions are joined by "OR", 
using SearchBean (see one of the next subsections) or setting a contextual 
property "search.lax.property.match" will help. The former option is better 
when you need to know the list of all the properties which have been used in 
the expression, even those which will not be possible to use for the actual 
search; the latter option will simply have the unrecognized properties 
ignored.</p><p>Note that a "search.decode.values" property can be used to have 
the 'reserved' characters such as FIQL ',' or ';' characters passed as 
percent-encoded characters as part of
  the search property values.</p><h3 
id="JAX-RSSearch-Mappingofquerypropertiestobeanproperties">Mapping of query 
properties to bean properties</h3><p>As noted above, when a 'typed' bean such 
as Book.class is used to capture the expressions, a property found in the query 
expression that can not be mapped to a specific Book property will lead to an 
exception being reported or it can be optionally ignored. In the reality, there 
is a number of reasons why the direct match between properties found in query 
expressions and in capturing beans may not be ideal:</p><ul 
class="alternate"><li>Capturing beans may evolve independently of the actual 
queries; for example, a working query such as "name==b" will break if a Book 
'name' gets renamed to 'title' which will make it difficult to have the queries 
bookmarked.</li><li>Direct match will simply not work for cases where an actual 
bean property does not belong to the capturing bean itself but to one of its 
child properties; for example, a JPA2 Bo
 ok entity may have an OwnerInfo bean with Name bean property which does 
contain a primitive 'name' property.</li></ul><p>The preferred approach, when 
working with typed beans, is to register a bean properties map, using a 
"search.bean.property.map" contextual property or directly with SearchContext. 
For example, given</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+</div></div><p>Note that a searchContext.getCondition(Book. class) call may 
return an arbitrary complex SearchCondition, it can be a simple 
primitiveexpression or a more complex, composite one.</p><h2 
id="JAX-RSSearch-Capturingthequeries">Capturing the queries</h2><p>For the 
query expression to be captured, a bean like Book.class is instantiated and has 
all the search properties injected into it. A complex composite expression will 
be 'injected' into a number of Book instances - something that may have to be 
optimized.</p><p>Note that by default, a bean such as Book class needs to have 
a matching property per every property name found in the FIQL expression, for 
example, given a 'name==b;id==123' expression, the Book class would need to 
have 'name' and 'id' properties available. The reason for this strict mode 
being enabled by default is that ignoring a property which can not be captured 
may lead to a false or unexpected match, for example, if Book 'name' property 
has been renamed t
 o 'title' then ignoring the 'name' property will lead to a wider match. Thus, 
if the property does not exist, 
org.apache.cxf.jaxrs.ext.search.PropertyNotFoundException will be thrown; 
capturing it can let returning an empty response or retry with the more lax 
mode, see the next paragraph.</p><p>When a more lax parsing of FIQL expressions 
is expected, for example, where the primitive expressions are joined by "OR", 
using SearchBean (see one of the next subsections) or setting a contextual 
property "search.lax.property.match" will help. The former option is better 
when you need to know the list of all the properties which have been used in 
the expression, even those which will not be possible to use for the actual 
search; the latter option will simply have the unrecognized properties 
ignored.</p><p>Note that a "search.decode.values" property can be used to have 
the 'reserved' characters such as FIQL ',' or ';' characters passed as 
percent-encoded characters as part of the search prope
 rty values.</p><h3 
id="JAX-RSSearch-Mappingofquerypropertiestobeanproperties">Mapping of query 
properties to bean properties</h3><p>As noted above, when a 'typed' bean such 
as Book.class is used to capture the expressions, a property found in the query 
expression that can not be mapped to a specific Book property will lead to an 
exception being reported or it can be optionally ignored. In the reality, there 
is a number of reasons why the direct match between properties found in query 
expressions and in capturing beans may not be ideal:</p><ul 
class="alternate"><li>Capturing beans may evolve independently of the actual 
queries; for example, a working query such as "name==b" will break if a Book 
'name' gets renamed to 'title' which will make it difficult to have the queries 
bookmarked.</li><li>Direct match will simply not work for cases where an actual 
bean property does not belong to the capturing bean itself but to one of its 
child properties; for example, a JPA2 Book entity may hav
 e an OwnerInfo bean with Name bean property which does contain a primitive 
'name' property.</li></ul><p>The preferred approach, when working with typed 
beans, is to register a bean properties map, using a "search.bean.property.map" 
contextual property or directly with SearchContext. For example, given</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class Book {
 
     private int id;
@@ -220,7 +220,6 @@ public class Name {
     private String name;
     //setters and getters omitted for brevity
 }
-
 </pre>
 </div></div><p>and the following map:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;map&gt;
@@ -262,9 +261,9 @@ SQLPrinterVisitor&lt;SearchBean&gt; visi
 sc.accept(visitor);
 assertEquals("SELECT LEVEL_COLUMN FROM table 
               WHERE LEVEL_COLUMN &gt; '10'",
-              visitor.getResult());
+              visitor.getQuery());
 </pre>
-</div></div><h2 id="JAX-RSSearch-Convertingthequeries">Converting the 
queries</h2><p>SearchCondition can also be used to convert the search 
requirements (originally expressed in FIQL/OData) into other query languages. 
<br clear="none"> A custom <a shape="rect" class="external-link" 
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchConditionVisitor.java";>SearchConditionVisitor</a>
 implementation can be used to convert SearchCondition objects into custom 
expressions or typed objects. CXF ships visitors for converting expressions to 
SQL, JPA 2.0 CriteriaQuery or TypedQuery, Lucene Query.</p><h3 
id="JAX-RSSearch-SQL">SQL</h3><p>org.apache.cxf.jaxrs.ext.search.sql.SQLPrinterVisitor
 can be used for creating SQL expressions. For example:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><h2 id="JAX-RSSearch-Convertingthequeries">Converting the 
queries</h2><p>SearchCondition can also be used to convert the search 
requirements (originally expressed in FIQL/OData) into other query languages. 
<br clear="none"> A custom <a shape="rect" class="external-link" 
href="https://github.com/apache/cxf/blob/master/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchConditionVisitor.java";
 rel="nofollow">SearchConditionVisitor</a> implementation can be used to 
convert SearchCondition objects into custom expressions or typed objects. CXF 
ships visitors for converting expressions to SQL, JPA 2.0 CriteriaQuery or 
TypedQuery, Lucene Query.</p><h3 
id="JAX-RSSearch-SQL">SQL</h3><p>org.apache.cxf.jaxrs.ext.search.sql.SQLPrinterVisitor
 can be used for creating SQL expressions. For example:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">// ?_s="name==ami*;level=gt=10"
 SearchCondition&lt;Book&gt; sc = searchContext.getCondition(Book.class);
 SQLPrinterVisitor&lt;Book&gt; visitor = new 
SQLPrinterVisitor&lt;Book&gt;("table");
@@ -274,7 +273,7 @@ assertEquals("SELECT * FROM table
               name LIKE 'ami%' 
               AND 
               level &gt; '10'",
-              visitor.getResult());
+              visitor.getQuery());
 </pre>
 </div></div><p>Note that SQLPrinterVisitor can also be initialized with the 
names of columns and the field aliases map:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">// ?_s="level=gt=10"
@@ -287,7 +286,7 @@ SQLPrinterVisitor&lt;Book&gt; visitor =
 sc.accept(visitor);
 assertEquals("SELECT LEVEL_COLUMN FROM table 
               WHERE LEVEL_COLUMN &gt; '10'",
-              visitor.getResult());
+              visitor.getQuery());
 </pre>
 </div></div><p>The fields map can help hide the names of the actual table 
columns/record fields from the Web frontend. Example, the users will know that 
the 'level' property is available while internally it will be converted to a 
LEVEL_COLUMN name.</p><h3 id="JAX-RSSearch-JPA2.0">JPA 2.0</h3><p>CXF 2.6.4 and 
CXF 2.7.1 introduce org.apache.cxf.jaxrs.ext.search.jpa.JPATypedQueryVisitor 
and org.apache.cxf.jaxrs.ext.search.jpa.JPACriteriaQueryVisitor which can be 
used to capture FIQL/OData expressions into <br clear="none"> 
javax.persistence.TypedQuery or javax.persistence.criteria.CriteriaQuery 
objects.</p><p>For example, given:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class Book {
@@ -319,8 +318,6 @@ public class Address {
     private String street;
     //setters and getters omitted for brevity
 }
-
-
 </pre>
 </div></div><p>the following code can be used:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">import javax.persistence.EntityManager;
@@ -385,18 +382,18 @@ for (Tuple tuple : tuples) {
 </pre>
 </div></div><p>Note that JPACriteriaQueryVisitor will automatically set 
aliases for an expression like "tuple.get('id', String.class)" to work.<br 
clear="none"> JPACriteriaQueryVisitor will be enhanced to support more of JPA2 
advanced constructs in time.</p><p>Or, instead of using Tuple, use a capturing 
bean like BeanInfo:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public static class BookInfo {
-        private int id;
-        private String title;
+    private int id;
+    private String title;
 
-        public BookInfo() {
+    public BookInfo() {
             
-        }
+    }
         
-        public BookInfo(Integer id, String title) {
-            this.id = id;
-            this.title = title;
-        }
-        //setters and getters omitted for brevity
+    public BookInfo(Integer id, String title) {
+        this.id = id;
+        this.title = title;
+    }
+    //setters and getters omitted for brevity
  }
 
 // actual application code:
@@ -417,7 +414,6 @@ TypedQuery&lt;BookInfo&gt; query = visit
 
 List&lt;BookInfo&gt; bookInfo = typedQuery.getResultList();
 return bookInfo;
-
 </pre>
 </div></div><p>JPA2 typed converters also support join operations in cases 
when explicit collections are used, for example, given:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@Entity(name = "Book")
@@ -484,7 +480,6 @@ public class BookReview {
         BAD
     }
 }
-
 </pre>
 </div></div><p>the following will find "all the books with good reviews 
written by Ted":</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">SearchCondition&lt;Book&gt; filter = new 
FiqlParser&lt;Book&gt;(Book.class).parse("reviews.review==good;reviews.authors==Ted");
@@ -495,7 +490,6 @@ SearchConditionVisitor&lt;Book, TypedQue
 filter.accept(jpa);
 TypedQuery&lt;Book&gt; query = jpa.getQuery();
 return query.getResultList();
-
 </pre>
 </div></div><p>org.apache.cxf.jaxrs.ext.search.jpa.JPALanguageVisitor for 
converting FIQL/OData expressions into JPQL expressions have also been 
introduced.</p><h4 id="JAX-RSSearch-Countexpressions">Count 
expressions</h4><p>Count expressions are supported at the two 
levels,</p><p>First, one may want to get the count of records matching a given 
search expression, this actually can be done by checking the size of the result 
list:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">TypedQuery&lt;Book&gt; query = jpa.getQuery();
@@ -507,7 +501,6 @@ return query.getResultList().size();
 JPACriteriaQueryVisitor&lt;Book, Long&gt; jpa = new 
JPACriteriaQueryVisitor&lt;Book, Long&gt;(em, Book.class, Long.class);
 filter.accept(jpa);
 long count = jpa.count();
-
 </pre>
 </div></div><p>&#160;</p><p>Second, <strong>only when using FIQL</strong>, a 
count extension can be used. For example, one may want to find 'all the books 
written by at least two authors or all the books with no reviews'.<br 
clear="none"> If a collection entity such as BookReview has a non primitive 
type, then typing "reviews==0" is all what is needed, otherwise a count 
extension needs to be used, for example: "count(authors)=ge=2"</p><h3 
id="JAX-RSSearch-Lucene">Lucene</h3><p>Mapping of FIQL/OData expressions to 
Lucene (4.0.0-BETA) Query is supported starting from CXF 2.7.1. Please notice 
that starting from CXF 3.0.2, the Lucene version has been upgraded to 4.9.0 in 
order to benefit from query builders and other 
improvements.</p><p>org.apache.cxf.jaxrs.ext.search.lucene.LuceneQueryVisitor 
can be used to support the default (content) field or specific custom field 
queries.<br clear="none"> Queries for specific terms and phrases are 
supported.</p><p>Example, "find the documents conta
 ining a 'text' term":</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">import org.apache.lucene.search.Query;
@@ -553,15 +546,14 @@ LdapQueryVisitor&lt;Condition&gt; visito
 
 filter.accept(visitor.visitor());
 String ldap = visitor.getQuery();
-
 </pre>
 </div></div><h3 id="JAX-RSSearch-HBase">HBase</h3><p>&#160;</p><p>CXF 3.0.2 
introduces an initial support for querying HBase databases. Please see <a 
shape="rect" class="external-link" 
href="https://fisheye6.atlassian.com/browse/cxf/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/hbase/HBaseVisitorTest.java?r=35b9209c04154bb00f1168cbeaa94314af070609";
 rel="nofollow">this test</a> for more information.</p><h3 
id="JAX-RSSearch-Customvisitors">Custom visitors</h3><p>In cases when a custom 
conversion has to be done, a converter for doing the untyped (example, SQL) or 
typed (example, JPA2 TypedQuery) conversions can be provided.</p><h4 
id="JAX-RSSearch-Untypedconverters">Untyped converters</h4><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class CustomSQLVisitor&lt;T&gt; extends 
AbstractSearchConditionVisitor&lt;T, String&gt; {
 
-private String tableName;
-private StringBuilder sb = new StringBuilder();
+    private String tableName;
+    private StringBuilder sb = new StringBuilder();
 
-public void visit(SearchCondition&lt;T&gt; sc) {
+    public void visit(SearchCondition&lt;T&gt; sc) {
         
         if (sb == null) {
             sb = new StringBuilder();
@@ -595,9 +587,9 @@ public void visit(SearchCondition&lt;T&g
 </div></div><h4 id="JAX-RSSearch-Typedconverters">Typed 
converters</h4><p>import org.custom.search.Query;</p><div class="code panel 
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class CustomTypedVisitor&lt;T&gt; extends 
AbstractSearchConditionVisitor&lt;T, Query&gt; {
 
-private Stack&lt;List&lt;Query&gt;&gt; queryStack = new 
Stack&lt;List&lt;Query&gt;&gt;();
+    private Stack&lt;List&lt;Query&gt;&gt; queryStack = new 
Stack&lt;List&lt;Query&gt;&gt;();
 
-public void visit(SearchCondition&lt;T&gt; sc) {
+    public void visit(SearchCondition&lt;T&gt; sc) {
                 
         PrimitiveStatement statement = sc.getStatement();
         if (statement != null) {
@@ -623,7 +615,7 @@ public void visit(SearchCondition&lt;T&g
         }
     }
 
-    public Query getResult() {
+    public Query getQuery() {
         return queryStack.peek().get(0);
     }
 }
@@ -643,9 +635,8 @@ public class SearchEngine {
         // note that the original search expression can also be retrieved 
         // using a SearchContext.getSearchExpression() method
 }
-
 </pre>
-</div></div><h2 
id="JAX-RSSearch-ConvertingthequerieswithQueryContext">Converting the queries 
with QueryContext</h2><p><a shape="rect" class="external-link" 
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/QueryContext.java";>QueryContext</a>
 is the helper context available from CXF 2.7.1 which makes it simpler for the 
application code to<br clear="none"> get the converted query expression, with 
the actual converter/visitor registered as the jaxrs contextual property, for 
example:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+</div></div><h2 
id="JAX-RSSearch-ConvertingthequerieswithQueryContext">Converting the queries 
with QueryContext</h2><p><a shape="rect" class="external-link" 
href="https://github.com/apache/cxf/blob/master/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/QueryContext.javahe/cxf/jaxrs/ext/search/QueryContext.java";
 rel="nofollow">QueryContext</a> is the helper context available from CXF 2.7.1 
which makes it simpler for the application code to<br clear="none"> get the 
converted query expression, with the actual converter/visitor registered as the 
jaxrs contextual property, for example:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">import java.util.ArrayList;
 import java.util.List;
 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
@@ -666,7 +657,6 @@ SQLPrinterVisitor&lt;SearchBean&gt; sqlV
 sqlVisitor.setVisitorState(new SBThrealLocalVisitorState());
 sf.getProperties(true).put("search.visitor", sqlVisitor);
 
-
 sf.setResourceClasses(BookStore.class);
 server = sf.create();
 </pre>
@@ -698,7 +688,6 @@ assertEquals("(a==a1,a==a2)", exp);
 // GET /search?a=a1&amp;b=b1
 exp = searchContext.getSearchExpression();
 assertEquals("(a==a1;b==b1)", exp);
-
 </pre>
 </div></div><p>Also, by default, if a query property name ends with "From" 
then "=ge=" (greater or equals to) will be used, and if ends with "Till" then 
"=lt=" will be used, for example:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">// GET /search?ageFrom=10&amp;ageTill=20
@@ -861,7 +850,7 @@ public class BooksResource {
 
 }
 </pre>
-</div></div><p>Note this code assumes that "bookId" is mapped to "Book.id" 
property with the help of the contextual "search.bean.property.map" property as 
explained earlier.</p><h2 id="JAX-RSSearch-Validation">Validation</h2><p>First 
option is to have a bean capturing specific property values do a domain 
specific validation. For example, a Book.class may have its setName(String 
name) method validating the name value. <br clear="none"> Another option is to 
inject a custom <a shape="rect" class="external-link" 
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/visitor/PropertyValidator.java";>validator</a>
 into a visitor which is used to build the untyped or typed 
query.</p><p>Finally, avoid letting users to use properties whose values which 
can not be well validated in the application code. Using a typed capturing bean 
like Book.class offers a perfect option to limit a number of supported 
properties to the ones known t
 o be related to Books.</p><p>Bean Validation 1.1 can also be used.</p><h2 
id="JAX-RSSearch-Buildingthequeries">Building the queries</h2><h3 
id="JAX-RSSearch-FIQL">FIQL</h3><p>CXF 2.4.0 introduces <a shape="rect" 
class="external-link" 
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/client/SearchConditionBuilder.java";>SearchConditionBuilder</a>
 which makes it simpler to build FIQL queries. SearchConditionBuilder is an 
abstract class that returns a FIQL builder by default:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>Note this code assumes that "bookId" is mapped to "Book.id" 
property with the help of the contextual "search.bean.property.map" property as 
explained earlier.</p><h2 id="JAX-RSSearch-Validation">Validation</h2><p>First 
option is to have a bean capturing specific property values do a domain 
specific validation. For example, a Book.class may have its setName(String 
name) method validating the name value. <br clear="none"> Another option is to 
inject a custom <a shape="rect" class="external-link" 
href="https://github.com/apache/cxf/blob/master/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/visitor/PropertyValidator.java";
 rel="nofollow">validator</a> into a visitor which is used to build the untyped 
or typed query.</p><p>Finally, avoid letting users to use properties whose 
values which can not be well validated in the application code. Using a typed 
capturing bean like Book.class offers a perfect option to limit a number of 
supported properties to t
 he ones known to be related to Books.</p><p>Bean Validation 1.1 can also be 
used.</p><h2 id="JAX-RSSearch-Buildingthequeries">Building the queries</h2><h3 
id="JAX-RSSearch-FIQL">FIQL</h3><p>CXF 2.4.0 introduces <a shape="rect" 
class="external-link" 
href="https://github.com/apache/cxf/blob/master/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/client/SearchConditionBuilder.java";
 rel="nofollow">SearchConditionBuilder</a> which makes it simpler to build FIQL 
queries. SearchConditionBuilder is an abstract class that returns a FIQL 
builder by default:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">SearchConditionBuilder b = 
SearchConditionBuilder.instance();
 String fiqlQuery = b.is("id").greaterThan(123).query();
 
@@ -908,8 +897,6 @@ assertEquals("(foo==20,foo==10);bar=lt=1
 
 String ret = 
b.is("foo").equalTo(10).and("bar").lessThan(10).wrap().or("bar").greaterThan(25).query();
 assertEquals("(foo==20;bar=lt=10),bar=gt=25", ret);
-
-
 </pre>
 </div></div><p>&#160;</p><h2 id="JAX-RSSearch-Usingdatesinqueries">Using dates 
in queries</h2><p>By default, the date values have to have the following <a 
shape="rect" class="external-link" 
href="http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html";
 rel="nofollow">format</a>: "yyyy-MM-dd", for example:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">?_search=date=le=2010-03-11


Reply via email to