Author: buildbot
Date: Fri Apr 17 09:58:13 2020
New Revision: 1059447
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 Fri Apr 17 09:58:13
2020
@@ -117,12 +117,12 @@ Apache CXF -- JAX-RS Search
<td height="100%">
<!-- Content -->
<div class="wiki-content">
-<div id="ConfluenceContent"><h1 id="JAX-RSSearch-JAX-RSSearch">JAX-RS
Search</h1><p> </p><p><style type="text/css">/*<![CDATA[*/
-div.rbtoc1543399006854 {padding: 0px;}
-div.rbtoc1543399006854 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1543399006854 li {margin-left: 0px;padding-left: 0px;}
+<div id="ConfluenceContent"><h1 id="JAX-RSSearch-JAX-RSSearch">JAX-RS
Search</h1><p><br clear="none"></p><p><style type="text/css">/*<![CDATA[*/
+div.rbtoc1587117448774 {padding: 0px;}
+div.rbtoc1587117448774 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1587117448774 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1543399006854">
+/*]]>*/</style></p><div class="toc-macro rbtoc1587117448774">
<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>
@@ -131,7 +131,7 @@ div.rbtoc1543399006854 li {margin-left:
</li><li><a shape="rect"
href="#JAX-RSSearch-Mappingofquerypropertiestocolumn/fieldnames">Mapping of
query properties to column/field names</a></li><li><a shape="rect"
href="#JAX-RSSearch-SearchBean">SearchBean</a></li><li><a shape="rect"
href="#JAX-RSSearch-Convertingthequeries">Converting the queries</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSSearch-SQL">SQL</a></li><li><a shape="rect"
href="#JAX-RSSearch-JPA2.0">JPA 2.0</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSSearch-Countexpressions">Count expressions</a></li></ul>
-</li><li><a shape="rect" href="#JAX-RSSearch-Lucene">Lucene</a></li><li><a
shape="rect" href="#JAX-RSSearch-LDAP">LDAP</a></li><li><a shape="rect"
href="#JAX-RSSearch-HBase">HBase</a></li><li><a shape="rect"
href="#JAX-RSSearch-Customvisitors">Custom visitors</a>
+</li><li><a shape="rect" href="#JAX-RSSearch-Lucene">Lucene</a></li><li><a
shape="rect" href="#JAX-RSSearch-LDAP">LDAP</a></li><li><a shape="rect"
href="#JAX-RSSearch-Customvisitors">Custom visitors</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSSearch-Untypedconverters">Untyped converters</a></li><li><a
shape="rect" href="#JAX-RSSearch-Typedconverters">Typed
converters</a></li><li><a shape="rect"
href="#JAX-RSSearch-Customparsing">Custom parsing</a></li></ul>
</li></ul>
</li><li><a shape="rect"
href="#JAX-RSSearch-ConvertingthequerieswithQueryContext">Converting the
queries with QueryContext</a></li><li><a shape="rect"
href="#JAX-RSSearch-PlainqueriestoFIQLconversion">Plain queries to FIQL
conversion</a></li><li><a shape="rect"
href="#JAX-RSSearch-SearchExpressionsinURIPathsegments">Search Expressions in
URI Path segments</a></li><li><a shape="rect"
href="#JAX-RSSearch-Queriesinvolvingmultipleentities">Queries involving
multiple entities</a>
@@ -149,7 +149,7 @@ div.rbtoc1543399006854 li {margin-left:
</div><h2 id="JAX-RSSearch-AdvancedSearchQueries">Advanced Search
Queries</h2><p>CXF supports mapping the advanced query expressions to the typed
Search API with the help of query language specific parsers. 
 </p><h2 id="JAX-RSSearch-SupportedQueryLanguages">Supported Query
Languages</h2><h3 id="JAX-RSSearch-FeedItemQueryLanguage">Feed Item Query
Language</h3><p><a shape="rect" class="external-link"
href="http://tools.ietf.org/html/draft-nottingham-atompub-fiql-00"
rel="nofollow">Feed Item Query Language</a>(FIQL) is supported since CXF
2.3.0.</p><p>For example, the following query</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme:
Default">?_s=name==CXF;version=ge=2.2
</pre>
-</div></div><p>lets users search for all the Apache projects with the name
'CXF' and the version greater or equal to '2.2'. The initial '=' separates the
name of the query '_s' from the FIQL expression, while '==' and '=ge=' convey
'equals to' and 'greater or equals to' respectively.<br clear="none"> An
expression such as "name==CXF*" can be used to do the partial equality check
(example: the name should start from "CXF").</p><p>More complex composite
expressions can also be expressed easily enough, examples:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>lets users search for all the Apache projects with the name
'CXF' and the version greater or equal to '2.2'. The initial '=' separates the
name of the query '_s' from the FIQL expression, while '==' and '=ge=' convey
'equals to' and 'greater or equals to' respectively.<br clear="none">An
expression such as "name==CXF*" can be used to do the partial equality check
(example: the name should start from "CXF").</p><p>More complex composite
expressions can also be expressed easily enough, examples:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">// Find all employees
younger than 25 or older than 35 living in London
/employees?_s=(age=lt=25,age=gt=35);city==London
@@ -162,7 +162,7 @@ div.rbtoc1543399006854 li {margin-left:
/books?date=lt=2000-01-01;date=gt=1999-01-01;(sub==math,sub==physics)
</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> </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&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">
+</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 operators
, 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><br
clear="none"></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&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 conditiona
l expressions 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"><dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-search</artifactId>
@@ -263,7 +263,7 @@ assertEquals("SELECT LEVEL_COLUMN FROM t
WHERE LEVEL_COLUMN > '10'",
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="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">
+</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">//
?_s="name==ami*;level=gt=10"
SearchCondition<Book> sc = searchContext.getCondition(Book.class);
SQLPrinterVisitor<Book> visitor = new
SQLPrinterVisitor<Book>("table");
@@ -288,7 +288,7 @@ assertEquals("SELECT LEVEL_COLUMN FROM t
WHERE LEVEL_COLUMN > '10'",
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><p><strong>Warning</strong>: Using the SQLPrinterVisitor
may leave your service open to SQL injection attacks. Please take appropriate
steps to avoid these attacks (for example validating queries using a custom
PropertyValidator, or <a shape="rect" class="external-link"
href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_4:_Escaping_All_User-Supplied_Input"
rel="nofollow">manually escaping</a> the input values).</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.persiste
nce.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">
+</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><p><strong>Warning</strong>: Using the SQLPrinterVisitor
may leave your service open to SQL injection attacks. Please take appropriate
steps to avoid these attacks (for example validating queries using a custom
PropertyValidator, or <a shape="rect" class="external-link"
href="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_4:_Escaping_All_User-Supplied_Input"
rel="nofollow">manually escaping</a> the input values).</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.persisten
ce.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">public class Book {
private String title;
@@ -380,7 +380,7 @@ 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">
+</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">public static class
BookInfo {
private int id;
private String title;
@@ -502,7 +502,7 @@ JPACriteriaQueryVisitor<Book, Long>
filter.accept(jpa);
long count = jpa.count();
</pre>
-</div></div><p> </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">
+</div></div><p><br clear="none"></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 docume
nts containing 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">import
org.apache.lucene.search.Query;
SearchCondition<SearchBean> filter = new
FiqlParser<SearchBean>(SearchBean.class).parse("ct==text");
@@ -537,7 +537,7 @@ LuceneQueryVisitor<SearchBean> luc
lucene.visit(filter);
org.apache.lucene.search.Query query = lucene.getQuery();</pre>
-</div></div><p> </p><h3 id="JAX-RSSearch-LDAP">LDAP</h3><p>Mapping of
FIQL/OData expressions to LDAP queries as defined by <a shape="rect"
class="external-link" href="http://tools.ietf.org/html/rfc4515"
rel="nofollow">RFC-4515</a> is supported starting from CXF 2.7.1 with the help
of org.apache.cxf.jaxrs.ext.search.ldap.LdapQueryVisitor. Use this visitor when
working with LDAP or OSGI.</p><p>Here is a summary of LDAP filter
operators:</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>"="</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Equal</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>"!"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Not Equal</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>
"<="</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>">="</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>"&"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>AND</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>"|"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>OR</p></td></tr></tbody></table></div><p>FIQL "=le="
and "=lt=" will both map to "<=", while "=ge=" and "=gt=" to
">=".</p><p>For example:</p><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>FIQL</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>LDAP</p></th></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>"name==bar*"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>"(name=ba
r*)"</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>"name!=bar"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>"(!name=bar)"</p></td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p>"name!=bar;id=gt=10"</p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p>"(&(!name=bar)(id>=10))"</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>"name!=bar;(id=gt=10,id=lt=5)"</p></td><td colspan="1"
rowspan="1"
class="confluenceTd"><p>"(&(!name=bar)(|(id>=10)(id<=5)))"</p></td></tr></tbody></table></div><p>The
converter is created like all other converters:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p><br clear="none"></p><h3
id="JAX-RSSearch-LDAP">LDAP</h3><p>Mapping of FIQL/OData expressions to LDAP
queries as defined by <a shape="rect" class="external-link"
href="http://tools.ietf.org/html/rfc4515" rel="nofollow">RFC-4515</a> is
supported starting from CXF 2.7.1 with the help of
org.apache.cxf.jaxrs.ext.search.ldap.LdapQueryVisitor. Use this visitor when
working with LDAP or OSGI.</p><p>Here is a summary of LDAP filter
operators:</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>"="</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Equal</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>"!"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Not Equal</p></td></tr><tr><td colspan="1" rowspan="1"
class="conflu
enceTd"><p>"<="</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>">="</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>"&"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>AND</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>"|"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>OR</p></td></tr></tbody></table></div><p>FIQL "=le="
and "=lt=" will both map to "<=", while "=ge=" and "=gt=" to
">=".</p><p>For example:</p><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>FIQL</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>LDAP</p></th></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>"name==bar*"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><
p>"(name=bar*)"</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>"name!=bar"</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>"(!name=bar)"</p></td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p>"name!=bar;id=gt=10"</p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p>"(&(!name=bar)(id>=10))"</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>"name!=bar;(id=gt=10,id=lt=5)"</p></td><td colspan="1"
rowspan="1"
class="confluenceTd"><p>"(&(!name=bar)(|(id>=10)(id<=5)))"</p></td></tr></tbody></table></div><p>The
converter is created like all other converters:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">// FIQL "oclass=Bar"
// map 'oclass' used in the FIQL query to the actual property name,
'objectClass'
@@ -547,7 +547,7 @@ LdapQueryVisitor<Condition> visito
filter.accept(visitor.visitor());
String ldap = visitor.getQuery();
</pre>
-</div></div><p>Note that <a shape="rect" class="external-link"
href="https://issues.apache.org/jira/browse/CXF-7701">since</a> CXF 3.2.5 the
query values are encoded by default, to prevent possible LDAP injection
attacks. If you want to support wildcard searching with the LdapQueryVisitor
from CXF 3.2.5 onwards, it is necessary to set the 'encodeQueryValues' property
of LdapQueryVisitor to 'false'.</p><h3
id="JAX-RSSearch-HBase">HBase</h3><p> </p><p>CXF 3.0.2 introduces an
initial support for querying HBase databases. Please see <a shape="rect"
class="external-link"
href="https://github.com/apache/cxf/blob/master/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/hbase/HBaseVisitorTest.java"
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 prov
ided.</p><h4 id="JAX-RSSearch-Untypedconverters">Untyped converters</h4><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><p>Note that <a shape="rect" class="external-link"
href="https://issues.apache.org/jira/browse/CXF-7701">since</a> CXF 3.2.5 the
query values are encoded by default, to prevent possible LDAP injection
attacks. If you want to support wildcard searching with the LdapQueryVisitor
from CXF 3.2.5 onwards, it is necessary to set the 'encodeQueryValues' property
of LdapQueryVisitor to 'false'.</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">public class
CustomSQLVisitor<T> extends AbstractSearchConditionVisitor<T,
String> {
private String tableName;
@@ -636,7 +636,7 @@ public class SearchEngine {
// 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="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">
+</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">import
java.util.ArrayList;
import java.util.List;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
@@ -680,7 +680,7 @@ WebClient client = WebClient.create(addr
client.accept("application/xml");
List<Book> books = client.getCollection(Book.class);
</pre>
-</div></div><p>Note, given that SQLPrinterVisitor will be shared between
multiple requests it has to be made thread-safe by injecting a thread-local<br
clear="none">
org.apache.cxf.jaxrs.ext.search.visitor.SBThrealLocalVisitorState. This is not
required when the visitor is created in the code on the per-request
basis.</p><p>Custom visitors which are expected to be singletons and have the
state accumulating between multiple visit calls have to be thread safe. Utility
org.apache.cxf.jaxrs.ext.search.visitor.ThrealLocalVisitorState class can be
used.</p><h2 id="JAX-RSSearch-PlainqueriestoFIQLconversion">Plain queries to
FIQL conversion</h2><p>If you'd like to generalize the processing of search
queries and use FIQL visitors, you may want to consider setting up a contextual
property "search.use.plain.queries" to "true" and get the plain query
expressions converted to FIQL expressions internally.</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelConte
nt pdl">
+</div></div><p>Note, given that SQLPrinterVisitor will be shared between
multiple requests it has to be made thread-safe by injecting a thread-local<br
clear="none">org.apache.cxf.jaxrs.ext.search.visitor.SBThrealLocalVisitorState.
This is not required when the visitor is created in the code on the per-request
basis.</p><p>Custom visitors which are expected to be singletons and have the
state accumulating between multiple visit calls have to be thread safe. Utility
org.apache.cxf.jaxrs.ext.search.visitor.ThrealLocalVisitorState class can be
used.</p><h2 id="JAX-RSSearch-PlainqueriestoFIQLconversion">Plain queries to
FIQL conversion</h2><p>If you'd like to generalize the processing of search
queries and use FIQL visitors, you may want to consider setting up a contextual
property "search.use.plain.queries" to "true" and get the plain query
expressions converted to FIQL expressions internally.</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelConten
t pdl">
<pre class="brush: java; gutter: false; theme: Default">// GET
/search?a=a1&a=v2
String exp = searchContext.getSearchExpression();
assertEquals("(a==a1,a==a2)", exp);
@@ -694,10 +694,10 @@ assertEquals("(a==a1;b==b1)", exp);
String exp = searchContext.getSearchExpression();
assertEquals("(age=ge=10,age=le=20)", exp);
</pre>
-</div></div><p>This can allow the plain query expressions mapped to typed bean
properties and further used with all the existing converters.</p><h2
id="JAX-RSSearch-SearchExpressionsinURIPathsegments">Search Expressions in URI
Path segments</h2><p>By default, a FIQL expression is expected to be available
in either '_s' or '_search' query.<br clear="none"> For example, "find all the
books with an 'id' property value less than 123":</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>This can allow the plain query expressions mapped to typed bean
properties and further used with all the existing converters.</p><h2
id="JAX-RSSearch-SearchExpressionsinURIPathsegments">Search Expressions in URI
Path segments</h2><p>By default, a FIQL expression is expected to be available
in either '_s' or '_search' query.<br clear="none">For example, "find all the
books with an 'id' property value less than 123":</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">GET /books?_s=id=lt=123
</pre>
-</div></div><p>Starting from CXF 2.6.2, it is possible to work with FIQL
expressions included in URI path segments, for example, the same query can be
expressed<br clear="none"> in a number of ways:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>Starting from CXF 2.6.2, it is possible to work with FIQL
expressions included in URI path segments, for example, the same query can be
expressed<br clear="none">in a number of ways:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">GET /books/id=lt=123
GET /books[id=lt=123]
GET /books(id=lt=123)
@@ -753,7 +753,7 @@ public class BooksResource {
}
</pre>
-</div></div><p>Note that if you have an expression added to a URI path segment
with a ";" character acting as a separator, example, "/books;id=lt=123",<br
clear="none"> or if an expression itself includes ";", example,
"/books[id=lt=123;id=gt=300]" ("find all the books with id less than 123 or
greater than 300") <br clear="none"> then a boolean contextual property
"ignore.matrix.parameters" has to be set to "true" for the runtime to avoid
splitting the path segment into the path value and matrix parameters.</p><h2
id="JAX-RSSearch-Queriesinvolvingmultipleentities">Queries involving multiple
entities</h2><h3 id="JAX-RSSearch-Basicqueries">Basic queries</h3><p>Consider
the query like "find chapters with a given chapter id from all the books with
'id' less than 123".<br clear="none"> One easy way to manage such queries is to
make FIQL and JAX-RS work together. For example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>Note that if you have an expression added to a URI path segment
with a ";" character acting as a separator, example, "/books;id=lt=123",<br
clear="none">or if an expression itself includes ";", example,
"/books[id=lt=123;id=gt=300]" ("find all the books with id less than 123 or
greater than 300") <br clear="none">then a boolean contextual property
"ignore.matrix.parameters" has to be set to "true" for the runtime to avoid
splitting the path segment into the path value and matrix parameters.</p><h2
id="JAX-RSSearch-Queriesinvolvingmultipleentities">Queries involving multiple
entities</h2><h3 id="JAX-RSSearch-Basicqueries">Basic queries</h3><p>Consider
the query like "find chapters with a given chapter id from all the books with
'id' less than 123".<br clear="none">One easy way to manage such queries is to
make FIQL and JAX-RS work together. 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">@Path("search")
public class BooksResource {
@Context
@@ -850,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="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">
+</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 th
e 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">SearchConditionBuilder
b = SearchConditionBuilder.instance();
String fiqlQuery = b.is("id").greaterThan(123).query();
@@ -898,7 +898,7 @@ 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> </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">
+</div></div><p><br clear="none"></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">?_search=date=le=2010-03-11
</pre>
</div></div><p>A custom date format can be supported. Use "search.date-format"
contextual property, example, "search.date-format"="yyyy-MM-dd'T'HH:mm:ss" will
let users type:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
@@ -916,10 +916,10 @@ FiqlSearchConditionBuilder bCustom = new
String ret = bCustom.is("foo").equalTo(d).query();
assertEquals("foo==2011-03-01T12:34:00", ret);
</pre>
-</div></div><div class="action-body flooded"><p> </p><h3
id="JAX-RSSearch-Relativedates">Relative dates</h3><p>Date value can be
specified as a duration from the current date/time, as its string
representation, "PnYnMnDTnHnMnS".<br clear="none"> Resulted date will be
calculated as a current date + specified duration. For example:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><div class="action-body flooded"><p><br clear="none"></p><h3
id="JAX-RSSearch-Relativedates">Relative dates</h3><p>Date value can be
specified as a duration from the current date/time, as its string
representation, "PnYnMnDTnHnMnS".<br clear="none">Resulted date will be
calculated as a current date + specified duration. 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">?_search=date=ge=-P90D
</pre>
-</div></div><p> </p><p>This query will search for a date which is 90 days
in the past or newer.</p></div><h2
id="JAX-RSSearch-Alternativequerylanguages">Alternative query
languages</h2><p>Custom org.apache.cxf.jaxrs.ext.search.SearchConditionParser
implementations can be registered as a "search.parser" contextual property
starting from CXF 3.0.0-milestone2.</p><h3
id="JAX-RSSearch-OData">OData</h3><p> </p><p>Please use a
"search.query.parameter.name" contextual property to indicate to the runtime
that an OData '$filter' query option needs to be checked for the query
expression and a "search.parser" property to point to the instance of
org.apache.cxf.jaxrs.ext.search.odata.ODataParser, as shown in this <a
shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerODataSearchTest.java">test</a>,
see the startServers function.</p><p>And here is also an XML Spring
configuration e
xample (using SearchBean in this specific case):</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p><br clear="none"></p><p>This query will search for a date which
is 90 days in the past or newer.</p></div><h2
id="JAX-RSSearch-Alternativequerylanguages">Alternative query
languages</h2><p>Custom org.apache.cxf.jaxrs.ext.search.SearchConditionParser
implementations can be registered as a "search.parser" contextual property
starting from CXF 3.0.0-milestone2.</p><h3
id="JAX-RSSearch-OData">OData</h3><p><br clear="none"></p><p>Please use a
"search.query.parameter.name" contextual property to indicate to the runtime
that an OData '$filter' query option needs to be checked for the query
expression and a "search.parser" property to point to the instance of
org.apache.cxf.jaxrs.ext.search.odata.ODataParser, as shown in this <a
shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerODataSearchTest.java">test</a>,
see the startServers function.</p><p>And here is also an XML
Spring configuration example (using SearchBean in this specific case):</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"> <cxf:bus>
<cxf:properties>
<entry key="search.query.parameter.name" value="$filter" />
@@ -931,14 +931,14 @@ assertEquals("foo==2011-03-01T12:34:00",
</cxf:properties>
</cxf:bus>
 </pre>
-</div></div><p> </p><p>Also note that <a shape="rect"
class="external-link" href="http://olingo.incubator.apache.org/">Apache
Olingo</a> offers its own visitor model which can be used to work with JPA2,
etc.</p><h2 id="JAX-RSSearch-ContentExtraction">Content
Extraction</h2><p>Starting from CXF 3.0.2, the content extraction support has
been added in order to complement the search capabilites with text extraction
from various document formats (PDF, ODF, DOC,TXT,RTF,...). It is based on
Apache Tika and is available in two shapes: raw content extraction
(TikaContentExtractor) and Lucene document content extraction
(TikaLuceneContentExtractor).</p><h3
id="JAX-RSSearch-UsingTikaContentExtractor">Using TikaContentExtractor</h3><p>The
purpose of Tika content extractor is to provide the essential support of text
extraction from supported document formats. Additionally, the metadata is being
extracted as well depending on the document format (author, modified, created,
pages, ...).
The TikaContentExtractor accepts the list of supported parsers and returns the
extracted metadata together with the desired extracted content format (by
default raw text). For example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p><br clear="none"></p><p>Also note that <a shape="rect"
class="external-link" href="http://olingo.incubator.apache.org/">Apache
Olingo</a> offers its own visitor model which can be used to work with JPA2,
etc.</p><h2 id="JAX-RSSearch-ContentExtraction">Content
Extraction</h2><p>Starting from CXF 3.0.2, the content extraction support has
been added in order to complement the search capabilites with text extraction
from various document formats (PDF, ODF, DOC,TXT,RTF,...). It is based on
Apache Tika and is available in two shapes: raw content extraction
(TikaContentExtractor) and Lucene document content extraction
(TikaLuceneContentExtractor).</p><h3
id="JAX-RSSearch-UsingTikaContentExtractor">Using TikaContentExtractor</h3><p>The
purpose of Tika content extractor is to provide the essential support of text
extraction from supported document formats. Additionally, the metadata is being
extracted as well depending on the document format (author, modified, created,
pa
ges, ...). The TikaContentExtractor accepts the list of supported parsers and
returns the extracted metadata together with the desired extracted content
format (by default raw text). 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">TikaContentExtractor
extractor = new TikaContentExtractor(new PDFParser(), true);
TikaContent content = extractor .extract( Files.newInputStream( new File(
"testPDF.pdf" ).toPath() ) );</pre>
</div></div><p>By default, the TikaContentExtractor  also performs the
content type detection and validation, which could be turned off using the
'validateMediaType' constructor argument.</p><h3
id="JAX-RSSearch-UsingTikaLuceneContentExtractor">Using TikaLuceneContentExtractor</h3><p>The
TikaLuceneContentExtractor is very similar to TikaContentExtractor but instead
of raw content and metadata it returns prepared Lucene document. However, in
order to properly create the Lucene document which is ready to be indexed,
TikaLuceneContentExtractor  accepts an additional parameter,
LuceneDocumentMetadata, with the field types and type converters. 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">LuceneDocumentMetadata
documentMetadata = new LuceneDocumentMetadata("contents").withField("modified",
Date.class);
TikaLuceneContentExtractor extractor = new TikaLuceneContentExtractor(new
PDFParser(), true);
Document document = extractor.extract( Files.newInputStream( new File(
"testPDF.pdf" ).toPath() ), documentMetadata );</pre>
-</div></div><p>At this point, the document is ready to be analyzed and
indexed. The TikaLuceneContentExtractor uses LuceneDocumentMetadata to
create the properly typed document fields and currently supports DoubleField,
FloatField, LongField, IntField, IntField, TextField (for content)
and StringField (also used to store dates).</p><p>To demonstrate the full power
of the CXF 3.0.2 content extraction and search capabiities, the demo project
'jax_rs_search' has been developed and is distributed in the samples bundle.
The project could be found in the <a shape="rect" class="external-link"
href="https://github.com/apache/cxf/tree/master/distribution/src/main/release/samples/jax_rs/search"
rel="nofollow">official Apache CXF Github repository</a>. It integrates
together Apache CXF, Apache Lucene and Apache Tika showing off some advanced
features related to custom analyzers and different filter criteria (keyword
and  phrase search).</p><pre> </pre></div>
+</div></div><p>At this point, the document is ready to be analyzed and
indexed. The TikaLuceneContentExtractor uses LuceneDocumentMetadata to
create the properly typed document fields and currently supports DoubleField,
FloatField, LongField, IntField, IntField, TextField (for content)
and StringField (also used to store dates).</p><p>To demonstrate the full power
of the CXF 3.0.2 content extraction and search capabiities, the demo project
'jax_rs_search' has been developed and is distributed in the samples bundle.
The project could be found in the <a shape="rect" class="external-link"
href="https://github.com/apache/cxf/tree/master/distribution/src/main/release/samples/jax_rs/search"
rel="nofollow">official Apache CXF Github repository</a>. It integrates
together Apache CXF, Apache Lucene and Apache Tika showing off some advanced
features related to custom analyzers and different filter criteria (keyword
and  phrase search).</p><pre><br clear="none"></pre></div>
</div>
<!-- Content -->
</td>