Author: buildbot
Date: Fri Nov 16 16:48:01 2012
New Revision: 838604
Log:
Production update by buildbot for cxf
Modified:
websites/production/cxf/content/cache/docs.pageCache
websites/production/cxf/content/docs/jax-rs-advanced-features.html
Modified: websites/production/cxf/content/cache/docs.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/cxf/content/docs/jax-rs-advanced-features.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-advanced-features.html
(original)
+++ websites/production/cxf/content/docs/jax-rs-advanced-features.html Fri Nov
16 16:48:01 2012
@@ -436,7 +436,46 @@ assertEquals("SELECT LEVEL_COLUMN FROM t
<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 expressions into <br clear="none">
javax.persistence.TypedQuery or javax.persistence.criteria.CriteriaQuery
objects.</p>
-<p>For example:</p>
+<p>For example, given:</p>
+
+<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
+<pre class="code-java">
+
+<span class="code-keyword">public</span> class Book {
+
+ <span class="code-keyword">private</span> <span
class="code-object">String</span> title;
+ <span class="code-keyword">private</span> Date date;
+ <span class="code-keyword">private</span> OwnerInfo ownerinfo;
+ <span class="code-comment">//setters and getters omitted <span
class="code-keyword">for</span> brewity
+</span>}
+
+@Embeddable
+<span class="code-keyword">public</span> class OwnerInfo {
+
+ <span class="code-keyword">private</span> Address address;
+ <span class="code-keyword">private</span> Name name;
+ <span class="code-comment">//setters and getters omitted <span
class="code-keyword">for</span> brewity
+</span>}
+
+@Embeddable
+<span class="code-keyword">public</span> class Name {
+
+ <span class="code-keyword">private</span> <span
class="code-object">String</span> name;
+ <span class="code-comment">//setters and getters omitted <span
class="code-keyword">for</span> brewity
+</span>}
+
+@Embeddable
+<span class="code-keyword">public</span> class Address {
+
+ <span class="code-keyword">private</span> <span
class="code-object">String</span> street;
+ <span class="code-comment">//setters and getters omitted <span
class="code-keyword">for</span> brewity
+</span>}
+
+
+</pre>
+</div></div>
+
+<p>the following code can be used:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
<pre class="code-java">
@@ -446,15 +485,15 @@ javax.persistence.TypedQuery or javax.pe
<span class="code-comment">// init EntityManager as required
</span><span class="code-keyword">private</span> EntityManager entityManager;
-<span class="code-comment">// Find the books owned by Barry, published
starting from the first month of 2000
-</span><span class="code-comment">// ?_s=<span
class="code-quote">"date=ge=2000-01-01;ownername=barry"</span>
+<span class="code-comment">// Find the books owned by Barry who lives in
London, published starting from the first month of 2000
+</span><span class="code-comment">// ?_s=<span
class="code-quote">"date=ge=2000-01-01;ownername=barry;address=london"</span>
</span>
<span class="code-comment">// <span class="code-keyword">this</span> map will
have to be set as a contextual property on the jaxrs endpoint
</span><span class="code-comment">// it assumes that Book bean has nested
OwnerInfo bean with nested Address and Name beans,
</span><span class="code-comment">// with the latter containing 'street' and
'name' property respectively
</span>
Map<<span class="code-object">String</span>, <span
class="code-object">String</span>> beanPropertiesMap = <span
class="code-keyword">new</span> HashMap<<span
class="code-object">String</span>, <span
class="code-object">String</span>>();
-beanPropertiesMap.put(<span class="code-quote">"street"</span>, <span
class="code-quote">"ownerInfo.address.street"</span>);
+beanPropertiesMap.put(<span class="code-quote">"address"</span>, <span
class="code-quote">"ownerInfo.address.street"</span>);
beanPropertiesMap.put(<span class="code-quote">"ownername"</span>, <span
class="code-quote">"ownerInfo.name.name"</span>);
<span class="code-comment">// the actual application code
@@ -473,32 +512,180 @@ List<Book> books = typedQuery.getR
<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
<pre class="code-java">
-Map<<span class="code-object">String</span>, <span
class="code-object">String</span>> beanPropertiesMap = <span
class="code-keyword">new</span> HashMap<<span
class="code-object">String</span>, <span
class="code-object">String</span>>();
-beanPropertiesMap.put(<span class="code-quote">"street"</span>, <span
class="code-quote">"ownerInfo.address.street"</span>);
+<span class="code-comment">// Find the books owned by Barry who lives in
London, published starting from the first month of 2000
+</span><span class="code-comment">// ?_s=<span
class="code-quote">"date=ge=2000-01-01;ownername=barry;address=london"</span>
+</span>
+<span class="code-comment">// <span class="code-keyword">this</span> map will
have to be set as a contextual property on the jaxrs endpoint
+</span>Map<<span class="code-object">String</span>, <span
class="code-object">String</span>> beanPropertiesMap = <span
class="code-keyword">new</span> HashMap<<span
class="code-object">String</span>, <span
class="code-object">String</span>>();
+beanPropertiesMap.put(<span class="code-quote">"address"</span>, <span
class="code-quote">"ownerInfo.address.street"</span>);
beanPropertiesMap.put(<span class="code-quote">"ownername"</span>, <span
class="code-quote">"ownerInfo.name.name"</span>);
<span class="code-comment">// the actual application code
-</span>SearchCondition<Book> sc = searchContext.getCondition(Book.class);
+</span><span class="code-comment">// Only Book 'id' and 'title' properties are
extracted from the list of found books
+</span>
+SearchCondition<Book> sc = searchContext.getCondition(Book.class);
JPACriteriaQueryVisitor<Book, Tuple> visitor =
- <span class="code-keyword">new</span> JPACriteriaQueryVisitor<Book,
Tuple>(entityManager, Book.class);
+ <span class="code-keyword">new</span> JPACriteriaQueryVisitor<Book,
Tuple>(entityManager, Book.class, Tuple.class);
sc.visit(visitor);
List<SingularAttribute<Book, ?>> selections = <span
class="code-keyword">new</span> LinkedList<SingularAttribute<Book,
?>>();
-selections.add(Book_.address);
+<span class="code-comment">// Book_ class is generated by JPA2 compiler
+</span>selections.add(Book_.id);
+selections.add(Book_.title);
visitor.selectTuple(selections);
TypedQuery<Tuple> query = visitor.getQuery();
-Tuple tuple = typedQuery.getSingleResult();
-<span class="code-object">String</span> street = tuple.get(<span
class="code-quote">"street"</span>, <span
class="code-object">String</span>.class);
+List<Tuple> tuples = typedQuery.getResultList();
+<span class="code-keyword">for</span> (Tuple tuple : tuples) {
+ <span class="code-object">int</span> bookId = tuple.get(<span
class="code-quote">"id"</span>, <span class="code-object">String</span>.class);
+ <span class="code-object">String</span> title = tuple.get(<span
class="code-quote">"title"</span>, <span
class="code-object">String</span>.class);
+ <span class="code-comment">// add bookId & title to the response data
+</span>}
</pre>
</div></div>
-<p>Note that JPACriteriaQueryVisitor will automatically set aliases for an
expression like "tuple.get('street', String.class)" to work.<br clear="none">
+
+
+<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" style="border-width: 1px;"><div class="codeContent
panelContent">
+<pre class="code-java">
+
+<span class="code-keyword">public</span> <span
class="code-keyword">static</span> class BookInfo {
+ <span class="code-keyword">private</span> <span
class="code-object">int</span> id;
+ <span class="code-keyword">private</span> <span
class="code-object">String</span> title;
+
+ <span class="code-keyword">public</span> BookInfo() {
+
+ }
+
+ <span class="code-keyword">public</span> BookInfo(<span
class="code-object">Integer</span> id, <span class="code-object">String</span>
title) {
+ <span class="code-keyword">this</span>.id = id;
+ <span class="code-keyword">this</span>.title = title;
+ }
+ <span class="code-comment">//setters and getters omitted <span
class="code-keyword">for</span> brewity
+</span> }
+
+<span class="code-comment">// actual application code:
+</span>
+SearchCondition<Book> sc = searchContext.getCondition(Book.class);
+JPACriteriaQueryVisitor<Book, BookInfo> visitor =
+ <span class="code-keyword">new</span> JPACriteriaQueryVisitor<Book,
BookInfo>(entityManager, Book.class, BookInfo.class);
+sc.visit(visitor);
+
+List<SingularAttribute<Book, ?>> selections = <span
class="code-keyword">new</span> LinkedList<SingularAttribute<Book,
?>>();
+<span class="code-comment">// Book_ class is generated by JPA2 compiler
+</span>selections.add(Book_.id);
+selections.add(Book_.title);
+
+visitor.selectConstruct(selections);
+
+TypedQuery<BookInfo> query = visitor.getQuery();
+
+List<BookInfo> bookInfo = typedQuery.getResultList();
+<span class="code-keyword">return</span> 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" style="border-width: 1px;"><div class="codeContent
panelContent">
+<pre class="code-java">
+
+@Entity(name = <span class="code-quote">"Book"</span>)
+<span class="code-keyword">public</span> class Book {
+
+ <span class="code-keyword">private</span> List<BookReview> reviews =
<span class="code-keyword">new</span> LinkedList<BookReview>();
+ <span class="code-keyword">private</span> List<<span
class="code-object">String</span>> authors = <span
class="code-keyword">new</span> LinkedList<<span
class="code-object">String</span>>();
+ <span class="code-comment">// other properties omitted
+</span>
+ @OneToMany
+ <span class="code-keyword">public</span> List<BookReview>
getReviews() {
+ <span class="code-keyword">return</span> reviews;
+ }
+
+ <span class="code-keyword">public</span> void
setReviews(List<BookReview> reviews) {
+ <span class="code-keyword">this</span>.reviews = reviews;
+ }
+
+ @ElementCollection
+ <span class="code-keyword">public</span> List<<span
class="code-object">String</span>> getAuthors() {
+ <span class="code-keyword">return</span> authors;
+ }
+
+ <span class="code-keyword">public</span> void setAuthors(List<<span
class="code-object">String</span>> authors) {
+ <span class="code-keyword">this</span>.authors = authors;
+ }
+}
+
+@Entity
+<span class="code-keyword">public</span> class BookReview {
+ <span class="code-keyword">private</span> Review review;
+ <span class="code-keyword">private</span> List<<span
class="code-object">String</span>> authors = <span
class="code-keyword">new</span> LinkedList<<span
class="code-object">String</span>>();
+ <span class="code-keyword">private</span> Book book;
+ <span class="code-comment">// other properties omitted
+</span>
+ <span class="code-keyword">public</span> Review getReview() {
+ <span class="code-keyword">return</span> review;
+ }
+
+ <span class="code-keyword">public</span> void setReview(Review review) {
+ <span class="code-keyword">this</span>.review = review;
+ }
+
+ @OneToOne
+ <span class="code-keyword">public</span> Book getBook() {
+ <span class="code-keyword">return</span> book;
+ }
+
+ <span class="code-keyword">public</span> void setBook(Book book) {
+ <span class="code-keyword">this</span>.book = book;
+ }
+
+ @ElementCollection
+ <span class="code-keyword">public</span> List<<span
class="code-object">String</span>> getAuthors() {
+ <span class="code-keyword">return</span> authors;
+ }
+
+ <span class="code-keyword">public</span> void setAuthors(List<<span
class="code-object">String</span>> authors) {
+ <span class="code-keyword">this</span>.authors = authors;
+ }
+
+ <span class="code-keyword">public</span> <span
class="code-keyword">static</span> <span class="code-keyword">enum</span>
Review {
+ GOOD,
+ BAD
+ }
+}
+
+</pre>
+</div></div>
+
+<p>the following will find "all the books with good reviews written by
Ted":</p>
+
+<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
+<pre class="code-java">
+
+SearchCondition<Book> filter = <span class="code-keyword">new</span>
FiqlParser<Book>(Book.class).parse(<span
class="code-quote">"reviews.review==good;reviews.authors==Ted"</span>);
+<span class="code-comment">// in practice, map <span
class="code-quote">"reviews.review"</span> to <span
class="code-quote">"review"</span>, <span
class="code-quote">"reviews.authors"</span> to <span
class="code-quote">"reviewAuthor"</span>
+</span><span class="code-comment">// and have a simple query like <span
class="code-quote">"review==good;reviewAuthor==Ted"</span> instead
+</span>
+SearchConditionVisitor<Book, TypedQuery<Book>> jpa = <span
class="code-keyword">new</span> JPATypedQueryVisitor<Book>(em,
Book.class);
+filter.accept(jpa);
+TypedQuery<Book> query = jpa.getQuery();
+<span class="code-keyword">return</span> query.getResultList();
+
+</pre>
+</div></div>
+
+
<p>org.apache.cxf.jaxrs.ext.search.jpa.JPALanguageVisitor for converting FIQL
expressions into JPQL expressions have also been introduced.</p>
<h3><a shape="rect" name="JAX-RSAdvancedFeatures-Lucene"></a>Lucene</h3>