You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by bu...@apache.org on 2015/09/15 14:35:08 UTC
svn commit: r965508 - in /websites/staging/olingo/trunk/content: ./
doc/odata4/tutorials/sqo_es/tutorial_sqo_es.html
doc/odata4/tutorials/sqo_f/tutorial_sqo_f.html
doc/odata4/tutorials/sqo_o/tutorial_sqo_o.html
Author: buildbot
Date: Tue Sep 15 12:35:08 2015
New Revision: 965508
Log:
Staging update by buildbot for olingo
Modified:
websites/staging/olingo/trunk/content/ (props changed)
websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.html
websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.html
websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.html
Propchange: websites/staging/olingo/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Tue Sep 15 12:35:08 2015
@@ -1 +1 @@
-1703158
+1703171
Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.html Tue Sep 15 12:35:08 2015
@@ -121,11 +121,11 @@ Again, in the present tutorial, weâ
</ol>
<hr />
<h1 id="1-prerequisites">1. Prerequisites<a class="headerlink" href="#1-prerequisites" title="Permanent link">¶</a></h1>
-<p>Same prerequisites as in <a href="http://olingo.apache.org/doc/odata4/tutorials/navigation/tutorial_navigation.html">Tutorial Part 4: Navigation</a> as well as basic knowledge about the concepts presented there.</p>
+<p>Same prerequisites as in <a href="doc/odata4/tutorials/navigation/tutorial_navigation.html">Tutorial Part 4: Navigation</a> as well as basic knowledge about the concepts presented there.</p>
<p>Furthermore, basic knowledge about <em>System Query Options</em> (see <a href="doc/odata4/tutorials/sqo_tcs/tutorial_sqo_tcs.html">Tutorial Part 5.1</a>) is helpful.</p>
<hr />
<h1 id="2-preparation">2. Preparation<a class="headerlink" href="#2-preparation" title="Permanent link">¶</a></h1>
-<p>Follow <a href="http://olingo.apache.org/doc/odata4/tutorials/navigation/tutorial_navigation.html">Tutorial Part 4: Navigation</a> or as shortcut import the <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip">attached project</a> into your Eclipse workspace.</p>
+<p>Follow <a href="doc/odata4/tutorials/navigation/tutorial_navigation.html">Tutorial Part 4: Navigation</a> or as shortcut import the <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip">attached project</a> into your Eclipse workspace.</p>
<p>Afterwards do a <em>Deploy and run</em>: it should be working.</p>
<hr />
<h1 id="3-implementation">3. Implementation<a class="headerlink" href="#3-implementation" title="Permanent link">¶</a></h1>
Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.html Tue Sep 15 12:35:08 2015
@@ -98,7 +98,7 @@
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<h1 id="how-to-build-an-odata-service-with-olingo-v4">How to build an OData Service with Olingo V4<a class="headerlink" href="#how-to-build-an-odata-service-with-olingo-v4" title="Permanent link">¶</a></h1>
-<h1 id="part-54-system-query-options-filter">Part 5.4: System Query Options: $filter<a class="headerlink" href="#part-54-system-query-options-filter" title="Permanent link">¶</a></h1>
+<h1 id="part-54-system-query-options-filter">Part 5.4: System Query Options: <code>$filter</code><a class="headerlink" href="#part-54-system-query-options-filter" title="Permanent link">¶</a></h1>
<h2 id="introduction">Introduction<a class="headerlink" href="#introduction" title="Permanent link">¶</a></h2>
<p>In the present tutorial, weâll continue implementing OData system query options, this time focusing on <code>$filter</code></p>
<p><strong>Note:</strong>
@@ -107,7 +107,7 @@ The full implementation of the OData ser
<ol>
<li>Preparation</li>
<li>Implementation<ol>
-<li>Implement $filter </li>
+<li>Implement <code>$filter</code></li>
</ol>
</li>
<li>Run the implemented service</li>
@@ -115,11 +115,11 @@ The full implementation of the OData ser
<li>Links</li>
</ol>
<h1 id="1-preparation">1. Preparation<a class="headerlink" href="#1-preparation" title="Permanent link">¶</a></h1>
-<p>Follow <em>Tutorial Part 1: Read Entity Collection</em> and <em>Tutorial Part 2: Read Entity</em> or as shortcut import the project attached to Tutorial Part 2 into your Eclipse workspace.</p>
+<p>Follow <a href="doc/odata4/tutorials/read/tutorial_read.html">Tutorial Part 1: Read Entity Collection</a> and <a href="doc/odata4/tutorials/readep/tutorial_readep.html">Tutorial Part 2: Read Entity</a> or as shortcut import the <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip">sample project zip</a> (<a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.md5">md5</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.sha512">sha512</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.asc">pgp</a>) attached to Tutorial Part 2 into your Eclipse workspace.</p>
<p>Afterwards do a <em>Deploy and run</em>: it should be working.</p>
<h1 id="2-implementation">2. Implementation<a class="headerlink" href="#2-implementation" title="Permanent link">¶</a></h1>
-<p>The system query options weâre focusing on are applied to the entity collection only, therefore our
-implementation for the $filter query options is done in the class
+<p>The system query options weâre focusing on are applied to the entity collection only, therefore our
+implementation for the <code>$filter</code> query options is done in the class
<code>myservice.mynamespace.service.DemoEntityCollectionProcessor</code></p>
<p>The general sequence is again:</p>
<ol>
@@ -129,11 +129,11 @@ implementation for the $filter query opt
<li>Serialize</li>
<li>Configure the response</li>
</ol>
-<h3 id="21-implement-filter">2.1 Implement $filter<a class="headerlink" href="#21-implement-filter" title="Permanent link">¶</a></h3>
+<h3 id="21-implement-filter">2.1 Implement <code>$filter</code><a class="headerlink" href="#21-implement-filter" title="Permanent link">¶</a></h3>
<h4 id="background">Background<a class="headerlink" href="#background" title="Permanent link">¶</a></h4>
<p>When requesting a list of entities from a service, the default behaviour is to return all entities on the list. The consumer of an OData service might want to be able to receive a subset by specifying certain criteria which each of the returned entities have to fulfill.<br />
For example, a common use case would be to request all products with a specified minimum and maximum price.
-OData supports this requirement with the system query option <strong>$filter</strong></p>
+OData supports this requirement with the system query option <code>$filter</code></p>
<p>It is specified as follows:</p>
<div class="codehilite"><pre>$<span class="n">filter</span><span class="p">=</span><span class="o"><</span><span class="n">BooleanExpression</span><span class="o">></span>
</pre></div>
@@ -142,23 +142,23 @@ OData supports this requirement with the
<p>See here for more details: <br />
<a href="http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part1-protocol/odata-v4.0-errata02-os-part1-protocol-complete.html#_Toc406398301">OData Version 4.0 Part 1: Protocol Plus Errata 02</a></p>
<p><a href="http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398094">OData Version 4.0 Part 2: URL Conventions Plus Errata 02</a></p>
-<p>The expression given by the <strong>$filter</strong> query option has to return a Boolean value when applied to a certain entity on the entity list. Iff the value returned for a given entity is <em>âtrueâ</em>, the service has to return the entity. Otherwise the service has to discard the entity.</p>
+<p>The expression given by the <code>$filter</code> query option has to return a Boolean value when applied to a certain entity on the entity list. If the value returned for a given entity is <em>âtrueâ</em>, the service has to return the entity. Otherwise the service has to discard the entity.</p>
<p><strong>Example</strong></p>
<p>First, just to remember how the full payload looks like, the ânormalâ query of the product:</p>
<p><a href="http://localhost:8080/DemoService/DemoService.svc/Products">http://localhost:8080/DemoService/DemoService.svc/Products</a></p>
<p><img alt="AllProductsWithoutFilter" src="no_filter.png" title="All products without filter" /></p>
<p>Now have a look to the following Uri:<br />
<a href="[http://localhost:8080/DemoService/DemoService.svc/Products?$filter=ID eq 1 or contains(Description,'1280')">http://localhost:8080/DemoService/DemoService.svc/Products?$filter=ID eq 1 or contains(Description,'1280')</a></p>
-<p>The $filter system query option has been applied to the Products Entity Collection. The client requests all products which fulfills the following condition: ID equals to one or the Description should contain the string â1280â</p>
+<p>The <code>$filter</code> system query option has been applied to the Products Entity Collection. The client requests all products which fulfills the following condition: ID equals to one or the Description should contain the string â1280â</p>
<p><img alt="ProductsWithFilter" src="filter_applied.png" title="Products with applied $filter" /></p>
<p><strong>Visitor pattern</strong></p>
<p>First things first, the Uri parser creates an <em>abstract syntax tree</em> (AST). An abstract syntax tree describes the expression in a hierarchical way. (see figure 1) For example to calculate the root node, all nodes below have to be calculated first. The idea is to traverse the tree in pre order (depth-first).</p>
-<p>Consider the following Uri </p>
+<p>Consider the following Uri</p>
<div class="codehilite"><pre>â<span class="o">/</span><span class="n">Products</span>?$<span class="n">format</span><span class="p">=(</span><span class="n">Price</span> <span class="n">lt</span> 2000<span class="p">)</span> <span class="n">and</span> <span class="n">contains</span><span class="p">(</span><span class="n">Description</span><span class="p">,</span>â<span class="n">Notebook</span>â<span class="p">)</span>â<span class="p">.</span>
</pre></div>
-<p>As you can see, the intention is to request all Products, which costs less than 2000 monetary units and contains the word âNotebookâ in their description. The expression is split up in two parts by the binary operator âandâ. To calculate the result of the âandâ node, the left and also the right child have to be calculated first. The left child itself is another binary operation. So to calculate âless thanâ the type and value of the property âPriceâ has to be determined. And so onâ¦</p>
+<p>As you can see, the intention is to request all Products, which costs less than 2000 monetary units and contains the word âNotebookâ in their description. The expression is split up in two parts by the binary operator âandâ. To calculate the result of the âandâ node, the left and also the right child have to be calculated first. The left child itself is another binary operation. So to calculate âless thanâ the type and value of the property âPriceâ has to be determined. And so on...</p>
<p><img alt="AbstractSyntaxTree" src="ast.png" title="Abstract syntax tree of the filter expression âPrice lt 2000 and contains(Description,âNotebookâ)" /></p>
<p>Key<br />
<img alt="AbstractSyntaxTree" src="keyAST.png" title="Key abstract syntax tree" /></p>
@@ -217,22 +217,22 @@ OData supports this requirement with the
</tr>
</tbody>
</table>
-<p>Olingo uses the vistor pattern to traverse the AST. Each of these actions is mapped to one method of the ExpressionVistor interface. You can see the name of the methods in last column of table 1. As service developers we have to implement this methods but we don`t have to take care about calling them. The libaray will call the proper method and we have only to calculate the result. </p>
+<p>Olingo uses the vistor pattern to traverse the AST. Each of these actions is mapped to one method of the ExpressionVistor interface. You can see the name of the methods in last column of table 1. As service developers we have to implement this methods but we do not have to take care about calling them. The libaray will call the proper method and we have only to calculate the result.</p>
<h4 id="implementation">Implementation<a class="headerlink" href="#implementation" title="Permanent link">¶</a></h4>
-<p>First we will create the <em>Filter Expression Visitor</em> and after that, we`ll integrate the just created Visitor in <em>EntityCollectionProcessor</em>.</p>
+<p>First we will create the <em>Filter Expression Visitor</em> and after that, we will integrate the just created Visitor in <code>EntityCollectionProcessor</code>.</p>
<p><strong>1.1 Create our FilterExpressionVisitor</strong></p>
-<p>Create a new class <em>FilterExpressionVisitor</em> in package <em>myservice.mynamespace.service</em> and<br />
-implement the Interface <em>org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor</em>. </p>
-<p>As you mentioned the interface needs a generic parameter.
-This generic type is used as (return) parameter for the visitXXX methods (e.g. <em>visitLiteral</em> ). It`s up to your implementation to
-choose a proper type for your use case. The main task is to keep track of the type and also the return value of a node in the abstract syntax tree.
-In real world scenarios it is common to build a statement to query a database or backend instead modifying the preloaded data. </p>
-<p>In this tutorial we will use just <em>Object</em> and pass the native Java values around.</p>
+<p>Create a new class <code>FilterExpressionVisitor</code> in package <code>myservice.mynamespace.service</code> and<br />
+implement the Interface <code>org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor</code>.</p>
+<p>As you mentioned the interface needs a generic parameter.
+This generic type is used as (return) parameter for the visitXXX methods (e.g. <code>visitLiteral</code> ). It is up to your implementation to
+choose a proper type for your use case. The main task is to keep track of the type and also the return value of a node in the abstract syntax tree.
+In real world scenarios it is common to build a statement to query a database or backend instead modifying the preloaded data.</p>
+<p>In this tutorial we will use just <code>Object</code> and pass the native Java values around.</p>
<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">FilterExpressionVisitor</span> <span class="kd">implements</span> <span class="n">ExpressionVisitor</span><span class="o"><</span><span class="n">Object</span><span class="o">></span> <span class="o">{</span>
</pre></div>
-<p>Please create also a constructor to pass an entity to our visitor implementation. </p>
+<p>Please create also a constructor to pass an entity to our visitor implementation.</p>
<div class="codehilite"><pre><span class="kd">private</span> <span class="n">Entity</span> <span class="n">currentEntity</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">FilterExpressionVisitor</span><span class="o">(</span><span class="n">Entity</span> <span class="n">currentEntity</span><span class="o">)</span> <span class="o">{</span>
@@ -243,18 +243,18 @@ In real world scenarios it is common to
<p><strong>1.2 Implement the interface</strong></p>
<p>In this basic tutorial we will implement only a subset of the Expression Visitor.
-The following methods will <strong>not</strong> be implemented. Add an <em>ODataApplicationException</em> to their bodies</p>
+The following methods will <strong>not</strong> be implemented. Add an <code>ODataApplicationException</code> to their bodies:</p>
<ul>
-<li>public Object visitTypeLiteral(EdmType type)</li>
-<li>public Object visitAlias(String aliasName)</li>
-<li>public Object visitEnum(EdmEnumType type, List<String> enumValues)</li>
-<li>public Object visitLambdaExpression(String lambdaFunction, String lambdaVariable, Expression expression)</li>
-<li>public Object visitLambdaReference(String variableName)</li>
+<li><code>public Object visitTypeLiteral(EdmType type)</code></li>
+<li><code>public Object visitAlias(String aliasName)</code></li>
+<li><code>public Object visitEnum(EdmEnumType type, List<String> enumValues)</code></li>
+<li><code>public Object visitLambdaExpression(String lambdaFunction, String lambdaVariable, Expression expression)</code></li>
+<li><code>public Object visitLambdaReference(String variableName)</code></li>
</ul>
<p><strong>Example</strong></p>
<div class="codehilite"><pre><span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Object</span> <span class="nf">visitTypeLiteral</span><span class="o">(</span><span class="n">EdmType</span> <span class="n">type</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">ExpressionVisitException</span><span class="o">,</span> <span class="n">ODataApplicationException</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Type literals are not implemented"</span><span class="o">,</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Type literals are not implemented"</span><span class="o">,</span>
<span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">NOT_IMPLEMENTED</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
</pre></div>
@@ -267,7 +267,7 @@ This method is been called if the curren
<span class="c1">// We have faith that the java type of Edm.Int32 is Integer</span>
<span class="kd">final</span> <span class="n">List</span><span class="o"><</span><span class="n">UriResource</span><span class="o">></span> <span class="n">uriResourceParts</span> <span class="o">=</span> <span class="n">member</span><span class="o">.</span><span class="na">getUriResourceParts</span><span class="o">();</span>
- <span class="c1">// Make sure that the resource path of the property contains only a single segment and a </span>
+ <span class="c1">// Make sure that the resource path of the property contains only a single segment and a</span>
<span class="c1">// primitive property has been addressed. We can be sure, that the property exists because </span>
<span class="c1">// the UriParser checks if the property has been defined in service metadata document.</span>
@@ -278,11 +278,11 @@ This method is been called if the curren
<span class="c1">// The OData specification allows in addition complex properties and navigation </span>
<span class="c1">// properties with a target cardinality 0..1 or 1.</span>
<span class="c1">// This means any combination can occur e.g. Supplier/Address/City</span>
- <span class="c1">// -> Navigation properties Supplier </span>
+ <span class="c1">// -> Navigation properties Supplier</span>
<span class="c1">// -> Complex Property Address</span>
<span class="c1">// -> Primitive Property City</span>
<span class="c1">// For such cases the resource path returns a list of UriResourceParts</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Only primitive properties are implemented in filter </span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Only primitive properties are implemented in filter</span>
<span class="s"> expressions"</span><span class="o">,</span> <span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">NOT_IMPLEMENTED</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
@@ -293,16 +293,16 @@ This method is been called if the curren
<p>The next method takes a String and has to return the type and also the value of literal. </p>
<p><strong>Example</strong> </p>
<ul>
-<li>"â1â" is a string with the value "1"</li>
-<li>"1" could be an Edm.Byte, Edm.SByte, Edm.Int16, Edm.Int32, Edm.Int64, Edm.Single, Edm.Double, Edm.Decimal with value 1</li>
+<li>"<code>â1â</code>" is a string with the value "<code>1</code>"</li>
+<li>"<code>1</code>" could be an Edm.Byte, Edm.SByte, Edm.Int16, Edm.Int32, Edm.Int64, Edm.Single, Edm.Double, Edm.Decimal with value 1</li>
</ul>
-<p>As you can see in this little example, it can be difficult to guess the right type. In this tutorial we will focus on Edm.Int32. </p>
+<p>As you can see in this little example, it can be difficult to guess the right type. In this tutorial we will focus on Edm.Int32.</p>
<p>In real world scenarios, there is something called ânumeric promotionâ, which converts numbers to the next higher type. <a href="http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398161">OData Version 4.0 Part 2: URL Conventions Plus Errata 02</a></p>
<div class="codehilite"><pre><span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">Object</span> <span class="nf">visitLiteral</span><span class="o">(</span><span class="n">Literal</span> <span class="n">literal</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">ExpressionVisitException</span><span class="o">,</span> <span class="n">ODataApplicationException</span> <span class="o">{</span>
<span class="c1">// To keep this tutorial simple, our filter expression visitor supports only Edm.Int32 and Edm.String</span>
<span class="c1">// In real world scenarios it can be difficult to guess the type of an literal.</span>
- <span class="c1">// We can be sure, that the literal is a valid OData literal because the URI Parser checks </span>
+ <span class="c1">// We can be sure, that the literal is a valid OData literal because the URI Parser checks</span>
<span class="c1">// the lexicographical structure</span>
<span class="c1">// String literals start and end with an single quotation mark</span>
@@ -319,7 +319,7 @@ This method is been called if the curren
<span class="k">try</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">Integer</span><span class="o">.</span><span class="na">parseInt</span><span class="o">(</span><span class="n">literalAsString</span><span class="o">);</span>
<span class="o">}</span> <span class="k">catch</span><span class="o">(</span><span class="n">NumberFormatException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Only Edm.Int32 and Edm.String literals are implemented"</span><span class="o">,</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Only Edm.Int32 and Edm.String literals are implemented"</span><span class="o">,</span>
<span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">NOT_IMPLEMENTED</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
@@ -328,21 +328,21 @@ This method is been called if the curren
<p><strong>Implement the operators</strong></p>
-<p>The first two implemented methods dealt on the leaves of the AST. Now we will implement the operations, which can be performed on these values.</p>
-<p>The idea behind the implementation is always the same. </p>
+<p>The first two implemented methods dealt on the leaves of the AST. Now we will implement the operations, which can be performed on these values.</p>
+<p>The idea behind the implementation is always the same.</p>
<ol>
<li>Check if the types fit together</li>
<li>If true => Calculate and return the result</li>
-<li>Otherwise => Throw an <em>ODataApplicationException</em> with StatusCode 400 Bad Request</li>
+<li>Otherwise => Throw an <code>ODataApplicationException</code> with StatusCode 400 Bad Request</li>
</ol>
-<p>OData supports two different unary operators. First there is the binary negation (<em>not</em>) and second the arithmetic minus (<em>-</em>). </p>
-<div class="codehilite"><pre><span class="kd">public</span> <span class="n">Object</span> <span class="nf">visitUnaryOperator</span><span class="o">(</span><span class="n">UnaryOperatorKind</span> <span class="n">operator</span><span class="o">,</span> <span class="n">Object</span> <span class="n">operand</span><span class="o">)</span>
+<p>OData supports two different unary operators. First there is the binary negation (<em>not</em>) and second the arithmetic minus (<em>-</em>).</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="n">Object</span> <span class="nf">visitUnaryOperator</span><span class="o">(</span><span class="n">UnaryOperatorKind</span> <span class="n">operator</span><span class="o">,</span> <span class="n">Object</span> <span class="n">operand</span><span class="o">)</span>
<span class="kd">throws</span> <span class="n">ExpressionVisitException</span><span class="o">,</span> <span class="n">ODataApplicationException</span> <span class="o">{</span>
- <span class="c1">// OData allows two different unary operators. We have to take care, that the type of the </span>
+ <span class="c1">// OData allows two different unary operators. We have to take care, that the type of the</span>
<span class="c1">// operand fits to the operand</span>
<span class="k">if</span><span class="o">(</span><span class="n">operator</span> <span class="o">==</span> <span class="n">UnaryOperatorKind</span><span class="o">.</span><span class="na">NOT</span> <span class="o">&&</span> <span class="n">operand</span> <span class="k">instanceof</span> <span class="n">Boolean</span><span class="o">)</span> <span class="o">{</span>
- <span class="c1">// 1.) boolean negation </span>
+ <span class="c1">// 1.) boolean negation</span>
<span class="k">return</span> <span class="o">!(</span><span class="n">Boolean</span><span class="o">)</span> <span class="n">operand</span><span class="o">;</span>
<span class="o">}</span> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="n">operator</span> <span class="o">==</span> <span class="n">UnaryOperatorKind</span><span class="o">.</span><span class="na">MINUS</span> <span class="o">&&</span> <span class="n">operand</span> <span class="k">instanceof</span> <span class="n">Integer</span><span class="o">){</span>
<span class="c1">// 2.) arithmetic minus</span>
@@ -350,7 +350,7 @@ This method is been called if the curren
<span class="o">}</span>
<span class="c1">// Operation not processed, throw an exception</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Invalid type for unary operator"</span><span class="o">,</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Invalid type for unary operator"</span><span class="o">,</span>
<span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">BAD_REQUEST</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
</pre></div>
@@ -361,9 +361,9 @@ This method is been called if the curren
<span class="kd">public</span> <span class="n">Object</span> <span class="nf">visitBinaryOperator</span><span class="o">(</span><span class="n">BinaryOperatorKind</span> <span class="n">operator</span><span class="o">,</span> <span class="n">Object</span> <span class="n">left</span><span class="o">,</span> <span class="n">Object</span> <span class="n">right</span><span class="o">)</span>
<span class="kd">throws</span> <span class="n">ExpressionVisitException</span><span class="o">,</span> <span class="n">ODataApplicationException</span> <span class="o">{</span>
- <span class="c1">// Binary Operators are split up in three different kinds. Up to the kind of the </span>
+ <span class="c1">// Binary Operators are split up in three different kinds. Up to the kind of the</span>
<span class="c1">// operator it can be applied to different types</span>
- <span class="c1">// - Arithmetic operations like add, minus, modulo, etc. are allowed on numeric </span>
+ <span class="c1">// - Arithmetic operations like add, minus, modulo, etc. are allowed on numeric</span>
<span class="c1">// types like Edm.Int32</span>
<span class="c1">// - Logical operations are allowed on numeric types and also Edm.String</span>
<span class="c1">// - Boolean operations like and, or are allowed on Edm.Boolean</span>
@@ -386,7 +386,7 @@ This method is been called if the curren
<span class="o">||</span> <span class="n">operator</span> <span class="o">==</span> <span class="n">BinaryOperatorKind</span><span class="o">.</span><span class="na">OR</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">evaluateBooleanOperation</span><span class="o">(</span><span class="n">operator</span><span class="o">,</span> <span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Binary operation "</span> <span class="o">+</span> <span class="n">operator</span><span class="o">.</span><span class="na">name</span><span class="o">()</span> <span class="o">+</span> <span class="s">" is not </span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Binary operation "</span> <span class="o">+</span> <span class="n">operator</span><span class="o">.</span><span class="na">name</span><span class="o">()</span> <span class="o">+</span> <span class="s">" is not</span>
<span class="s"> implemented"</span><span class="o">,</span> <span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">NOT_IMPLEMENTED</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
@@ -407,7 +407,7 @@ This method is been called if the curren
<span class="k">return</span> <span class="n">valueLeft</span> <span class="o">||</span> <span class="n">valueRight</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Boolean operations needs two numeric operands"</span><span class="o">,</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Boolean operations needs two numeric operands"</span><span class="o">,</span>
<span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">BAD_REQUEST</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
@@ -417,7 +417,7 @@ This method is been called if the curren
<span class="c1">// All types in our tutorial supports all logical operations, but we have to make sure that </span>
<span class="c1">// the types are equal</span>
<span class="k">if</span><span class="o">(</span><span class="n">left</span><span class="o">.</span><span class="na">getClass</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="n">right</span><span class="o">.</span><span class="na">getClass</span><span class="o">()))</span> <span class="o">{</span>
- <span class="c1">// Luckily all used types String, Boolean and also Integer support the interface </span>
+ <span class="c1">// Luckily all used types String, Boolean and also Integer support the interface</span>
<span class="c1">// Comparable</span>
<span class="kt">int</span> <span class="n">result</span><span class="o">;</span>
<span class="k">if</span><span class="o">(</span><span class="n">left</span> <span class="k">instanceof</span> <span class="n">Integer</span><span class="o">)</span> <span class="o">{</span>
@@ -427,7 +427,7 @@ This method is been called if the curren
<span class="o">}</span> <span class="k">else</span> <span class="k">if</span><span class="o">(</span><span class="n">left</span> <span class="k">instanceof</span> <span class="n">Boolean</span><span class="o">)</span> <span class="o">{</span>
<span class="n">result</span> <span class="o">=</span> <span class="o">((</span><span class="n">Comparable</span><span class="o"><</span><span class="n">Boolean</span><span class="o">>)</span> <span class="o">(</span><span class="n">Boolean</span><span class="o">)</span> <span class="n">left</span><span class="o">).</span><span class="na">compareTo</span><span class="o">((</span><span class="n">Boolean</span><span class="o">)</span> <span class="n">right</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Class "</span> <span class="o">+</span> <span class="n">left</span><span class="o">.</span><span class="na">getClass</span><span class="o">().</span><span class="na">getCanonicalName</span><span class="o">()</span> <span class="o">+</span> <span class="s">" not expected"</span><span class="o">,</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Class "</span> <span class="o">+</span> <span class="n">left</span><span class="o">.</span><span class="na">getClass</span><span class="o">().</span><span class="na">getCanonicalName</span><span class="o">()</span> <span class="o">+</span> <span class="s">" not expected"</span><span class="o">,</span>
<span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">INTERNAL_SERVER_ERROR</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
@@ -447,12 +447,12 @@ This method is been called if the curren
<span class="o">}</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Comparision needs two equal types"</span><span class="o">,</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Comparision needs two equal types"</span><span class="o">,</span>
<span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">BAD_REQUEST</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
-<span class="kd">private</span> <span class="n">Object</span> <span class="nf">evaluateArithmeticOperation</span><span class="o">(</span><span class="n">BinaryOperatorKind</span> <span class="n">operator</span><span class="o">,</span> <span class="n">Object</span> <span class="n">left</span><span class="o">,</span>
+<span class="kd">private</span> <span class="n">Object</span> <span class="nf">evaluateArithmeticOperation</span><span class="o">(</span><span class="n">BinaryOperatorKind</span> <span class="n">operator</span><span class="o">,</span> <span class="n">Object</span> <span class="n">left</span><span class="o">,</span>
<span class="n">Object</span> <span class="n">right</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">ODataApplicationException</span> <span class="o">{</span>
<span class="c1">// First check if the type of both operands is numerical</span>
@@ -474,21 +474,21 @@ This method is been called if the curren
<span class="k">return</span> <span class="n">valueLeft</span> <span class="o">%</span> <span class="n">valueRight</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Arithmetic operations needs two numeric </span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Arithmetic operations needs two numeric</span>
<span class="s"> operands"</span><span class="o">,</span> <span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">BAD_REQUEST</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</pre></div>
-<p>The last method we have to implement is <em>visitMethodCall</em>. The principle is always the same, check the types and calculate the return value. As a developer you can be sure, that the number of parameters fits to the MethodKind but the types have to be checked by yourself. E.g. <em>contains</em> takes two Strings and return <em>Edm.Boolean</em> but </p>
+<p>The last method we have to implement is <code>visitMethodCall</code>. The principle is always the same, check the types and calculate the return value. As a developer you can be sure, that the number of parameters fits to the MethodKind but the types have to be checked by yourself. E.g. <em>contains</em> takes two Strings and return <em>Edm.Boolean</em> but</p>
<div class="codehilite"><pre> $<span class="n">filter</span><span class="p">=</span><span class="n">contains</span><span class="p">(</span>123<span class="p">,</span>123<span class="p">)</span>
</pre></div>
-<p>would not lead to an error. It`s up to you to throw an exception.</p>
+<p>would not lead to an error. It is up to you to throw an exception.</p>
<div class="codehilite"><pre><span class="nd">@Override</span>
-<span class="kd">public</span> <span class="n">Object</span> <span class="nf">visitMethodCall</span><span class="o">(</span><span class="n">MethodKind</span> <span class="n">methodCall</span><span class="o">,</span> <span class="n">List</span><span class="o"><</span><span class="n">Object</span><span class="o">></span> <span class="n">parameters</span><span class="o">)</span>
+<span class="kd">public</span> <span class="n">Object</span> <span class="nf">visitMethodCall</span><span class="o">(</span><span class="n">MethodKind</span> <span class="n">methodCall</span><span class="o">,</span> <span class="n">List</span><span class="o"><</span><span class="n">Object</span><span class="o">></span> <span class="n">parameters</span><span class="o">)</span>
<span class="kd">throws</span> <span class="n">ExpressionVisitException</span><span class="o">,</span> <span class="n">ODataApplicationException</span> <span class="o">{</span>
<span class="c1">// To keep this tutorial small and simple, we implement only one method call</span>
@@ -500,11 +500,11 @@ This method is been called if the curren
<span class="k">return</span> <span class="n">valueParam1</span><span class="o">.</span><span class="na">contains</span><span class="o">(</span><span class="n">valueParam2</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Contains needs two parametes of type Edm.String"</span><span class="o">,</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Contains needs two parametes of type Edm.String"</span><span class="o">,</span>
<span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">BAD_REQUEST</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
- <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Method call "</span> <span class="o">+</span> <span class="n">methodCall</span> <span class="o">+</span> <span class="s">" not implemented"</span><span class="o">,</span>
+ <span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Method call "</span> <span class="o">+</span> <span class="n">methodCall</span> <span class="o">+</span> <span class="s">" not implemented"</span><span class="o">,</span>
<span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">NOT_IMPLEMENTED</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
@@ -512,7 +512,7 @@ This method is been called if the curren
<p><strong>2. EntityCollectionProcessor changes</strong></p>
-<p>The following section describes the simple approach to enable the EntityCollectionProcessor class and the readEntityCollection() method for $filter.</p>
+<p>The following section describes the simple approach to enable the EntityCollectionProcessor class and the readEntityCollection() method for <code>$filter</code>.</p>
<p>Just like in the previous tutorials, the data is first fetched from the backend, then the system query option is applied.</p>
<div class="codehilite"><pre><span class="n">EntityCollection</span> <span class="n">entityCollection</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="na">readEntitySetData</span><span class="o">(</span><span class="n">edmEntitySet</span><span class="o">);</span>
<span class="n">List</span><span class="o"><</span><span class="n">Entity</span><span class="o">></span> <span class="n">entityList</span> <span class="o">=</span> <span class="n">entityCollection</span><span class="o">.</span><span class="na">getEntities</span><span class="o">();</span>
@@ -521,12 +521,12 @@ This method is been called if the curren
<p>We will proceed according to these 4 steps:</p>
<ol>
-<li>Get the query option from the UriInfo. If null is returned then nothing has to be done. </li>
-<li>Get the expression from the query option </li>
+<li>Get the query option from the UriInfo. If null is returned then nothing has to be done.</li>
+<li>Get the expression from the query option</li>
<li>Instantiate our Expression Visitor and evaluate the result for each entity in the collection</li>
<li>Modify the EntityCollection based on the result of the expression</li>
</ol>
-<p><strong>2.1 Get the FilterOption from the uriInfo</strong></p>
+<p><strong>2.1 Get the FilterOption from the uriInfo</strong></p>
<div class="codehilite"><pre><span class="n">FilterOption</span> <span class="n">filterOption</span> <span class="p">=</span> <span class="n">uriInfo</span><span class="p">.</span><span class="n">getFilterOption</span><span class="p">();</span>
<span class="k">if</span><span class="p">(</span><span class="n">filterOption</span> !<span class="p">=</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
</pre></div>
@@ -543,10 +543,10 @@ This method is been called if the curren
<span class="n">Iterator</span><span class="o"><</span><span class="n">Entity</span><span class="o">></span> <span class="n">entityIterator</span> <span class="o">=</span> <span class="n">entityList</span><span class="o">.</span><span class="na">iterator</span><span class="o">();</span>
<span class="c1">// Evaluate the expression for each entity</span>
- <span class="c1">// If the expression is evaluated to "true", keep the entity otherwise remove it from </span>
+ <span class="c1">// If the expression is evaluated to "true", keep the entity otherwise remove it from</span>
<span class="c1">// the entityList</span>
<span class="k">while</span> <span class="o">(</span><span class="n">entityIterator</span><span class="o">.</span><span class="na">hasNext</span><span class="o">())</span> <span class="o">{</span>
- <span class="c1">// To evaluate the the expression, create an instance of the Filter Expression </span>
+ <span class="c1">// To evaluate the the expression, create an instance of the Filter Expression</span>
<span class="c1">// Visitor and pass the current entity to the constructor</span>
<span class="n">Entity</span> <span class="n">currentEntity</span> <span class="o">=</span> <span class="n">entityIterator</span><span class="o">.</span><span class="na">next</span><span class="o">();</span>
<span class="n">FilterExpressionVisitor</span> <span class="n">expressionVisitor</span> <span class="o">=</span> <span class="k">new</span> <span class="n">FilterExpressionVisitor</span><span class="o">(</span><span class="n">currentEntity</span><span class="o">);</span>
@@ -561,13 +561,13 @@ This method is been called if the curren
<div class="codehilite"><pre> <span class="c1">// The result of the filter expression must be of type Edm.Boolean</span>
<span class="k">if</span><span class="o">(</span><span class="n">visitorResult</span> <span class="k">instanceof</span> <span class="n">Boolean</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span><span class="o">(!</span><span class="n">Boolean</span><span class="o">.</span><span class="na">TRUE</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">visitorResult</span><span class="o">))</span> <span class="o">{</span>
- <span class="c1">// The expression evaluated to false (or null), so we have to remove the </span>
+ <span class="c1">// The expression evaluated to false (or null), so we have to remove the</span>
<span class="c1">// currentEntity from entityList</span>
<span class="n">entityIterator</span><span class="o">.</span><span class="na">remove</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"A filter expression must evaulate to type Edm.Boolean"</span><span class="o">,</span> <span class="n">HttpStatusCode</span><span class="o">.</span><span class="na">BAD_REQUEST</span><span class="o">.</span><span class="na">getStatusCode</span><span class="o">(),</span> <span class="n">Locale</span><span class="o">.</span><span class="na">ENGLISH</span><span class="o">);</span>
- <span class="o">}</span>
+ <span class="o">}</span>
<span class="o">}</span> <span class="c1">// End while</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">ExpressionVisitException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ODataApplicationException</span><span class="o">(</span><span class="s">"Exception in filter evaluation"</span><span class="o">,</span>
@@ -616,7 +616,7 @@ This method is been called if the curren
<li><a href="http://localhost:8080/DemoService/DemoService.svc/Products?$filter=contains(Name,'Ergo') and ID eq 3">http://localhost:8080/DemoService/DemoService.svc/Products?$filter=contains(Name,'Ergo') and ID eq 3</a></li>
</ul>
<h2 id="summary">Summary<a class="headerlink" href="#summary" title="Permanent link">¶</a></h2>
-<p>In this tutorial we have learned how to implement a simple service with $filter system query option. The very same Expression Visitor can be used to support advanced $orderby query options. The main difference is that, the Expression Visitor used by $orderby returns a (may be calculated) value of a primitive property instead a Boolean value.</p>
+<p>In this tutorial we have learned how to implement a simple service with <code>$filter</code> system query option. The very same Expression Visitor can be used to support advanced $orderby query options. The main difference is that, the Expression Visitor used by $orderby returns a (may be calculated) value of a primitive property instead a Boolean value.</p>
<h2 id="links">Links<a class="headerlink" href="#links" title="Permanent link">¶</a></h2>
<h3 id="tutorials">Tutorials<a class="headerlink" href="#tutorials" title="Permanent link">¶</a></h3>
<ul>
Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.html Tue Sep 15 12:35:08 2015
@@ -98,24 +98,25 @@
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<h1 id="how-to-build-an-odata-service-with-olingo-v4">How to build an OData Service with Olingo V4<a class="headerlink" href="#how-to-build-an-odata-service-with-olingo-v4" title="Permanent link">¶</a></h1>
-<h1 id="part-53-system-query-options-orderby">Part 5.3: System Query Options: $orderby<a class="headerlink" href="#part-53-system-query-options-orderby" title="Permanent link">¶</a></h1>
+<h1 id="part-53-system-query-options-orderby">Part 5.3: System Query Options: <code>$orderby</code><a class="headerlink" href="#part-53-system-query-options-orderby" title="Permanent link">¶</a></h1>
<h2 id="introduction">Introduction<a class="headerlink" href="#introduction" title="Permanent link">¶</a></h2>
-<p>In the present tutorial, weâll continue implementing OData system query options, this time focusing on <strong>$orderby</strong></p>
+<p>In the present tutorial, we will continue implementing OData system query options, this time focusing on <code>$orderby</code></p>
<p><strong>Note:</strong>
The full implementation of the OData service as described in the present tutorial can be found in the attached zip file that contains an Eclipse project that can be imported into your Eclipse workspace.</p>
<p><strong>Disclaimer:</strong>
-Again, in the present tutorial, weâll focus only on the relevant implementation, in order to keep the code small and simple. The sample code as it is, shouldnât be reused for advanced scenarios.</p>
+Again, in the present tutorial, we will focus only on the relevant implementation, in order to keep the code small and simple. The sample code as it is, shouldnât be reused for advanced scenarios.</p>
<p><strong>Table of Contents</strong></p>
-<div class="codehilite"><pre>1<span class="p">.</span> <span class="n">Prerequisites</span>
-2<span class="p">.</span> <span class="n">Preparation</span>
-3<span class="p">.</span> <span class="n">Implementation</span>
- 1<span class="p">.</span><span class="n">Implement</span> $<span class="n">ordergy</span>
-4<span class="p">.</span> <span class="n">Run</span> <span class="n">the</span> <span class="n">implemented</span> <span class="n">service</span>
-5<span class="p">.</span> <span class="n">Summary</span>
-6<span class="p">.</span> <span class="n">Links</span>
-</pre></div>
-
-
+<ol>
+<li>Prerequisites</li>
+<li>Preparation</li>
+<li>Implementation<ol>
+<li>Implement <code>$orderby</code></li>
+</ol>
+</li>
+<li>Run the implemented service</li>
+<li>Summary</li>
+<li>Links</li>
+</ol>
<p>__</p>
<h1 id="1-prerequisites">1. Prerequisites<a class="headerlink" href="#1-prerequisites" title="Permanent link">¶</a></h1>
<p>Same prerequisites as in <a href="http://olingo.apache.org/doc/odata4/tutorials/read/tutorial_read.html">Tutorial Part 1: Read Entity Collection</a>
@@ -125,7 +126,7 @@ Again, in the present tutorial, weâ
<p>Follow <em>Tutorial Part 1: Read Entity Collection</em> and <em>Tutorial Part 2: Read Entity</em> or as shortcut import the <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip">project</a> attached to Tutorial Part 2 into your Eclipse workspace.</p>
<p>Afterwards do a <em>Deploy and run</em>: it should be working.</p>
<h1 id="implementation">Implementation<a class="headerlink" href="#implementation" title="Permanent link">¶</a></h1>
-<p>The system query options weâre focusing on are applied to the entity collection only, therefore our
+<p>The system query options weâre focusing on are applied to the entity collection only, therefore our
implementation for all query options is done in the class
<em>myservice.mynamespace.service.DemoEntityCollectionProcessor</em></p>
<p>The general sequence is again:</p>
@@ -136,12 +137,12 @@ implementation for all query options is
<li>Serialize</li>
<li>Configure the response</li>
</ol>
-<h2 id="31-implement-orderby">3.1. Implement $orderby<a class="headerlink" href="#31-implement-orderby" title="Permanent link">¶</a></h2>
+<h2 id="31-implement-orderby">3.1. Implement <code>$orderby</code><a class="headerlink" href="#31-implement-orderby" title="Permanent link">¶</a></h2>
<p><strong>Background</strong></p>
<p>When requesting a list of entities from a service, it is up to the service implementation to decide in which order they are presented. This can depend on the backend data source, anyways, it is undefined.
-But the consumer of an OData service might want to be able to specify the order, according to his needs. </p>
+But the consumer of an OData service might want to be able to specify the order, according to his needs.</p>
<p>For example, a usual case would be that the list of entities is sorted as per default by its ID number, but for a user, the ID is not relevant and he would prefer a sorting e.g. by the name
-OData supports this requirement with the system query option <strong>$orderby</strong>
+OData supports this requirement with the system query option <code>$orderby</code>
It is specified as follows:</p>
<div class="codehilite"><pre>$<span class="n">orderby</span><span class="p">=</span><span class="o"><</span><span class="n">propertyName</span><span class="o">></span>
</pre></div>
@@ -157,10 +158,10 @@ $<span class="n">orderby</span><span cla
<p>See here for more details:
<a href="http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part1-protocol/odata-v4.0-errata02-os-part1-protocol-complete.html#_Toc406398305">OData Version 4.0 Part 1: Protocol Plus Errata 02</a></p>
<p><strong>Note:</strong>
-As of the OData specification, the $orderby system query option can be applied to multiple properties.
+As of the OData specification, the <code>$orderby</code> system query option can be applied to multiple properties.
In that case, the value is specified as comma-separated list.</p>
<p><strong>Example:</strong></p>
-<div class="codehilite"><pre><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">localhost</span><span class="p">:</span>8080<span class="o">/</span><span class="n">DemoService</span><span class="o">/</span><span class="n">DemoService</span><span class="p">.</span><span class="n">svc</span><span class="o">/</span><span class="n">Products</span>?$<span class="n">orderby</span><span class="p">=</span><span class="n">Name</span> <span class="n">asc</span><span class="p">,</span> <span class="n">Description</span> <span class="n">desc</span>
+<div class="codehilite"><pre><span class="o"><</span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">localhost</span><span class="p">:</span>8080<span class="o">/</span><span class="n">DemoService</span><span class="o">/</span><span class="n">DemoService</span><span class="p">.</span><span class="n">svc</span><span class="o">/</span><span class="n">Products</span>?$<span class="n">orderby</span><span class="p">=</span><span class="n">Name</span> <span class="n">asc</span><span class="p">,</span> <span class="n">Description</span> <span class="n">desc</span><span class="o">></span>
</pre></div>
@@ -172,7 +173,7 @@ We havenât used it in the present t
First, just to remember how the full payload looks like, the ânormalâ query of the product:
<a href="http://localhost:8080/DemoService/DemoService.svc/Products">http://localhost:8080/DemoService/DemoService.svc/Products</a></p>
<p><img alt="AllProductsNotSorted" src="products_unsorted.png" title="All products not sorted" /></p>
-<p>The following request specifies the sorting by the name.
+<p>The following request specifies the sorting by the name.
The order is ascending, if not specified elsewise.</p>
<p><a href="http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name">http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name</a></p>
<p><img alt="ProductsOrderedByNameAsc" src="products_bynameasc.png" title="All products sorted by name ascending" /></p>
@@ -205,7 +206,7 @@ The order is ascending, if not specified
<p>The instance of an OrderByOption can be asked for the list of its <em>OrderByItems</em>.
Why a list?
-Because the $orderby expression can be composed with multiple properties
+Because the <code>$orderby</code> expression can be composed with multiple properties
For example, for the following URL, we get 2 OrderByItems:</p>
<div class="codehilite"><pre><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">localhost</span><span class="p">:</span>8080<span class="o">/</span><span class="n">DemoService</span><span class="o">/</span><span class="n">DemoService</span><span class="p">.</span><span class="n">svc</span><span class="o">/</span><span class="n">Products</span>?$<span class="n">orderby</span><span class="p">=</span><span class="n">Name</span> <span class="n">asc</span><span class="p">,</span> <span class="n">Description</span> <span class="n">desc</span>
</pre></div>
@@ -259,15 +260,15 @@ So we have to retrieve that information
<p>The full implementation of the readEntityCollection() method:</p>
-<div class="codehilite"><pre><span class="kd">public</span> <span class="kt">void</span> <span class="nf">readEntityCollection</span><span class="o">(</span><span class="n">ODataRequest</span> <span class="n">request</span><span class="o">,</span> <span class="n">ODataResponse</span> <span class="n">response</span><span class="o">,</span> <span class="n">UriInfo</span> <span class="n">uriInfo</span><span class="o">,</span> <span class="n">ContentType</span> <span class="n">responseFormat</span><span class="o">)</span>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kt">void</span> <span class="nf">readEntityCollection</span><span class="o">(</span><span class="n">ODataRequest</span> <span class="n">request</span><span class="o">,</span> <span class="n">ODataResponse</span> <span class="n">response</span><span class="o">,</span> <span class="n">UriInfo</span> <span class="n">uriInfo</span><span class="o">,</span> <span class="n">ContentType</span> <span class="n">responseFormat</span><span class="o">)</span>
<span class="kd">throws</span> <span class="n">ODataApplicationException</span><span class="o">,</span> <span class="n">SerializerException</span> <span class="o">{</span>
- <span class="c1">// 1st retrieve the requested EntitySet from the uriInfo </span>
+ <span class="c1">// 1st retrieve the requested EntitySet from the uriInfo</span>
<span class="n">List</span><span class="o"><</span><span class="n">UriResource</span><span class="o">></span> <span class="n">resourcePaths</span> <span class="o">=</span> <span class="n">uriInfo</span><span class="o">.</span><span class="na">getUriResourceParts</span><span class="o">();</span>
- <span class="n">UriResourceEntitySet</span> <span class="n">uriResourceEntitySet</span> <span class="o">=</span> <span class="o">(</span><span class="n">UriResourceEntitySet</span><span class="o">)</span> <span class="n">resourcePaths</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
+ <span class="n">UriResourceEntitySet</span> <span class="n">uriResourceEntitySet</span> <span class="o">=</span> <span class="o">(</span><span class="n">UriResourceEntitySet</span><span class="o">)</span> <span class="n">resourcePaths</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
<span class="n">EdmEntitySet</span> <span class="n">edmEntitySet</span> <span class="o">=</span> <span class="n">uriResourceEntitySet</span><span class="o">.</span><span class="na">getEntitySet</span><span class="o">();</span>
- <span class="c1">// 2nd: fetch the data from backend </span>
+ <span class="c1">// 2nd: fetch the data from backend</span>
<span class="n">EntityCollection</span> <span class="n">entityCollection</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="na">readEntitySetData</span><span class="o">(</span><span class="n">edmEntitySet</span><span class="o">);</span>
<span class="n">List</span><span class="o"><</span><span class="n">Entity</span><span class="o">></span> <span class="n">entityList</span> <span class="o">=</span> <span class="n">entityCollection</span><span class="o">.</span><span class="na">getEntities</span><span class="o">();</span>
@@ -303,9 +304,9 @@ So we have to retrieve that information
<span class="n">compareResult</span> <span class="o">=</span> <span class="n">propertyValue1</span><span class="o">.</span><span class="na">compareTo</span><span class="o">(</span><span class="n">propertyValue2</span><span class="o">);</span>
<span class="o">}</span>
- <span class="c1">// if 'desc' is specified in the URI, change the order </span>
+ <span class="c1">// if 'desc' is specified in the URI, change the order</span>
<span class="k">if</span><span class="o">(</span><span class="n">orderByItem</span><span class="o">.</span><span class="na">isDescending</span><span class="o">()){</span>
- <span class="k">return</span> <span class="o">-</span> <span class="n">compareResult</span><span class="o">;</span> <span class="c1">// just reverse order </span>
+ <span class="k">return</span> <span class="o">-</span> <span class="n">compareResult</span><span class="o">;</span> <span class="c1">// just reverse order</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">compareResult</span><span class="o">;</span>
@@ -340,13 +341,13 @@ So we have to retrieve that information
<ul>
<li>The ânormalâ payload without query option <a href="http://localhost:8080/DemoService/DemoService.svc/Products">http://localhost:8080/DemoService/DemoService.svc/Products</a></li>
<li>Sort by Name ascending <a href="http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name">http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name</a></li>
-<li>Sort by Name descending <a href="http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name desc">http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name desc</a></li>
+<li>Sort by Name descending <a href="http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name desc">http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name desc</a></li>
<li>Sort by Description ascending <a href="http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description">http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description</a></li>
-<li>Sort by Description descending <a href="http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description desc">http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description desc</a></li>
+<li>Sort by Description descending <a href="http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description desc">http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description desc</a></li>
</ul>
<h1 id="5-summary">5. Summary<a class="headerlink" href="#5-summary" title="Permanent link">¶</a></h1>
-<p>In this tutorial we have learned how to implement a simple $orderby
-Weâve decided to not go for the advanced way of implementing $orderby, which would have been using an ExpressionVisitor, because that is treated in the $filter implementation.</p>
+<p>In this tutorial we have learned how to implement a simple <code>$orderby</code>.
+We have decided to not go for the advanced way of implementing <code>$orderby</code>, which would have been using an ExpressionVisitor, because that is treated in the <code>$filter</code> implementation.</p>
<h1 id="6-links">6. Links<a class="headerlink" href="#6-links" title="Permanent link">¶</a></h1>
<h3 id="tutorials">Tutorials<a class="headerlink" href="#tutorials" title="Permanent link">¶</a></h3>
<ul>
@@ -359,8 +360,12 @@ Weâve decided to not go for the adv
<li>Tutorial OData V4 service, part 5.3: System Query Options $orderby (this page)</li>
<li>Tutorial OData V4 service, part 5.4: <a href="/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.html">System Query Options $filter</a></li>
</ul>
-<p>OData specification: <a href="http://odata.org/">http://odata.org/</a> <br />
-Olingo Javadoc: <a href="http://olingo.apache.org/javadoc/odata4/index.html">http://olingo.apache.org/javadoc/odata4/index.html</a></p><div align="center">
+<h3 id="further-reading">Further reading<a class="headerlink" href="#further-reading" title="Permanent link">¶</a></h3>
+<ul>
+<li><a href="http://odata.org/">Official OData Homepage</a></li>
+<li><a href="http://www.odata.org/documentation/">OData documentation</a></li>
+<li><a href="/javadoc/odata4/index.html">Olingo Javadoc</a></li>
+</ul><div align="center">
<p>Copyright © 2013-2015, The Apache Software Foundation<br>
Apache Olingo, Olingo, Apache, the Apache feather, and
the Apache Olingo project logo are trademarks of the Apache Software