Modified: 
websites/staging/olingo/trunk/content/doc/odata4/tutorials/action/tutorial_bound_action.html
==============================================================================
--- 
websites/staging/olingo/trunk/content/doc/odata4/tutorials/action/tutorial_bound_action.html
 (original)
+++ 
websites/staging/olingo/trunk/content/doc/odata4/tutorials/action/tutorial_bound_action.html
 Wed Oct 25 06:11:48 2017
@@ -99,18 +99,17 @@
 }
 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">&para;</a></h1>
-<h1 id="part-6-action-imports-and-function-imports">Part 6: Action Imports and 
Function Imports<a class="headerlink" 
href="#part-6-action-imports-and-function-imports" title="Permanent 
link">&para;</a></h1>
+<h1 id="part-6-bound-actions">Part 6: Bound Actions<a class="headerlink" 
href="#part-6-bound-actions" title="Permanent link">&para;</a></h1>
 <p><strong>Table of Contents</strong></p>
 <div class="toc">
 <ul>
 <li><a href="#how-to-build-an-odata-service-with-olingo-v4">How to build an 
OData Service with Olingo V4</a></li>
-<li><a href="#part-6-action-imports-and-function-imports">Part 6: Action 
Imports and Function Imports</a><ul>
+<li><a href="#part-6-bound-actions">Part 6: Bound Actions</a><ul>
 <li><a href="#introduction">Introduction</a></li>
 <li><a href="#preparation">Preparation</a></li>
 <li><a href="#implementation">Implementation</a><ul>
 <li><a href="#extend-the-metadata-model">Extend the Metadata model</a></li>
 <li><a href="#extend-the-data-store">Extend the data store</a></li>
-<li><a 
href="#extend-the-entity-collection-and-the-entity-processor-to-handle-function-imports">Extend
 the entity collection and the entity processor to handle function 
imports</a></li>
 <li><a href="#implement-an-action-processor">Implement an action 
processor</a></li>
 </ul>
 </li>
@@ -126,7 +125,7 @@ h2:hover > .headerlink, h3:hover > .head
 </ul>
 </div>
 <h2 id="introduction">Introduction<a class="headerlink" href="#introduction" 
title="Permanent link">&para;</a></h2>
-<p>In the present tutorial, we’ll implement a function import and an action 
import as well.</p>
+<p>In the present tutorial, we’ll implement a bound action.</p>
 <p><strong>Note:</strong>
 The final source code can be found in the project <a 
href="https://git-wip-us.apache.org/repos/asf/olingo-odata4";>git repository</a>.
 A detailed description how to checkout the tutorials can be found <a 
href="/doc/odata4/tutorials/prerequisites/prerequisites.html">here</a>. <br />
@@ -152,81 +151,58 @@ root.</p>
 <li>A <em>complex property</em> or a <em>collection of complex 
properties</em></li>
 </ul>
 <p>In addition an <em>Action</em> can return void that means there is no 
return value. A <em>Function</em> must return a value.</p>
-<p>The definition gives us some parts where function and actions can be used. 
First an <em>Operation</em> can be bound or unbound. In this tutorial we will 
focus on unbound operations. Unbound operations are something like static 
methods in Java, so if one of these operations have parameters we have to pass 
all of them explicit to the operation.</p>
+<p>First an <em>Operation</em> can be bound or unbound.In this tutorial we 
will focus on bound operation. </p>
+<p>Bound actions support overloading (multiple actions having the same name 
within the same namespace) by binding parameter type. The combination of action 
name and the binding parameter type MUST be unique within a namespace.</p>
+<p>An action element MAY specify a Boolean value for the IsBound attribute.
+Actions whose IsBound attribute is false or not specified are considered 
unbound. Unbound actions are invoked through an action import.
+Actions whose IsBound attribute is true are considered bound. Bound actions 
are invoked by appending a segment containing the qualified action name to a 
segment of the appropriate binding parameter type within the resource path. 
Bound actions MUST contain at least one edm:Parameter element, and the first 
parameter is the binding parameter. The binding parameter can be of any type, 
and it MAY be nullable.</p>
+<p>Bound actions that return an entity or a collection of entities MAY specify 
a value for the EntitySetPath attribute if determination of the entity set for 
the return type is contingent on the binding parameter. The value for the 
EntitySetPath attribute consists of a series of segments joined together with 
forward slashes. The first segment of the entity set path MUST be the name of 
the binding parameter. The remaining segments of the entity set path MUST 
represent navigation segments or type casts.</p>
+<p>A navigation segment names the SimpleIdentifier of the navigation property 
to be traversed. A type cast segment names the QualifiedName of the entity type 
that should be returned from the type cast.</p>
 <p><strong>Example</strong></p>
-<p>For example there could be a function that calculates the VAT. The result 
depends on the one hand from the net price and on the other hand from the 
country in which the customer lives.</p>
-<p>Such a function can be expressed in the metadata document as follows</p>
-<div class="codehilite"><pre><span class="nt">&lt;Function</span> <span 
class="na">Name=</span><span class="s">&quot;CalculateVAT&quot;</span><span 
class="nt">&gt;</span>
-     <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;NetPrice&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.Decimal&quot;</span> <span class="na">Nullable=</span><span 
class="s">&quot;false&quot;</span><span class="nt">/&gt;</span>
-     <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;Country&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.String&quot;</span> <span class="na">Nullable=</span><span 
class="s">&quot;false&quot;</span><span class="nt">/&gt;</span>
-
-    <span class="nt">&lt;ReturnType</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.Decimal&quot;</span><span class="nt">/&gt;</span>
-<span class="nt">&lt;/Function&gt;</span>
-</pre></div>
-
-
-<p>To make this function statically callable we have to define a Function 
Import.</p>
-<div class="codehilite"><pre><span class="nt">&lt;EntityContainer</span> <span 
class="na">Name=</span><span class="s">&quot;Container&quot;</span><span 
class="nt">&gt;</span>
-     <span class="nt">&lt;FunctionImport</span> <span 
class="na">Name=</span><span class="s">&quot;StaticCalculateVAT&quot;</span>
-                     <span class="na">Function=</span><span 
class="s">&quot;CalculateVAT&quot;</span>
-                     <span class="na">IncludeInServiceDocument=</span><span 
class="s">&quot;true&quot;</span><span class="nt">/&gt;</span>
-<span class="nt">&lt;/EntityContainer&gt;</span>
-</pre></div>
-
-
-<p>To call such a Function Import the client issues a GET requests to a URL 
identifying the function import. The parameters are passed by using the so 
called inline parameter syntax. In this simple case such a call could look like 
this:</p>
-<div class="codehilite"><pre><span class="n">http</span><span 
class="p">:</span><span class="o">//</span><span class="n">host</span><span 
class="o">/</span><span class="n">myService</span><span class="o">/</span><span 
class="n">StaticCalculateVAT</span><span class="p">(</span><span 
class="n">NetPrice</span><span class="p">=</span>123<span 
class="p">.</span>00<span class="p">,</span><span class="n">Country</span><span 
class="p">=</span>’<span class="n">US</span>’<span class="p">)</span>
-</pre></div>
-
-
-<p>The definition talks about composing of functions. By default every 
function is Composable=false, that means there must be no further resource 
parts after the function call and there must also be no system query options. 
If a function is composable you are be able to use system query options. Which 
options are allowed in particular is based on the return type of the function. 
Further you can navigate to properties and use Navigation Properties to 
navigate to related entities as well.</p>
-<p>The definition of Actions / Action Imports in metadata document is similar 
to functions.</p>
-<div class="codehilite"><pre><span class="nt">&lt;Action</span> <span 
class="na">Name=</span><span class="s">&quot;Reset&quot;</span><span 
class="nt">&gt;</span>
-    <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;Amount&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.Int32&quot;</span><span class="nt">/&gt;</span>
+<p>For example there can be a bound action createOrders which is bound to the 
Customer entity having 2 parameters</p>
+<p>Such an action can be expressed in the metadata document as follows</p>
+<div class="codehilite"><pre><span class="nt">&lt;Action</span> <span 
class="na">Name=</span><span class="s">&quot;CreateOrder&quot;</span> <span 
class="na">isBound=</span><span class="s">”true”</span><span 
class="nt">&gt;</span>
+ <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;Customers&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;SampleEntities.Customer&quot;</span> <span 
class="na">Nullable=</span><span class="s">&quot;false&quot;</span><span 
class="nt">/&gt;</span>
+ <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;quantity&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.Int16&quot;</span> <span class="na">Nullable=</span><span 
class="s">&quot;false&quot;</span><span class="nt">/&gt;</span>
+ <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;discountCode&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.String&quot;</span> <span class="na">Nullable=</span><span 
class="s">&quot;false&quot;</span><span class="nt">/&gt;</span>
+ <span class="nt">&lt;ReturnType</span> <span class="na">Type=</span><span 
class="s">&quot;Collection(SampleEntities.Orders)&quot;</span><span 
class="nt">/&gt;</span>
 <span class="nt">&lt;/Action&gt;</span>
-
-<span class="nt">&lt;EntityContainer</span> <span class="na">Name=</span><span 
class="s">&quot;Container&quot;</span><span class="nt">&gt;</span>
-    <span class="nt">&lt;ActionImport</span> <span 
class="na">Name=</span><span class="s">&quot;StaticReset&quot;</span> <span 
class="na">Action=</span><span class="s">&quot;Reset&quot;</span><span 
class="nt">/&gt;</span>
-<span class="nt">&lt;/EntityContainer&gt;</span>
-</pre></div>
-
-
-<p>As you can see, this function does not return any value and takes one 
parameter “<em>Amount</em>” To call this action import, you have to issue 
an POST request to</p>
-<div class="codehilite"><pre><span class="n">http</span><span 
class="p">:</span><span class="o">//</span><span class="n">host</span><span 
class="o">/</span><span class="n">myService</span><span class="o">/</span><span 
class="n">StaticReset</span>
 </pre></div>
 
 
-<p>The parameters are passed within the body of the request. In this case such 
a body could look like the following (JSON - Syntax):</p>
-<div class="codehilite"><pre><span class="p">{</span>
-  <span class="nt">&quot;Amount&quot;</span><span class="p">:</span> <span 
class="mi">2</span>
-<span class="p">}</span>
+<p>To call such a bound action the client issues a POST request to a URL 
identifying the action. In this simple case such a call could look like 
this:</p>
+<div class="codehilite"><pre>  <span class="n">POST</span> <span 
class="n">http</span><span class="p">:</span><span class="o">//</span><span 
class="n">host</span><span class="o">/</span><span 
class="n">service</span><span class="o">/</span><span 
class="n">Customers</span><span class="p">(</span><span 
class="s">&#39;ALFKI&#39;</span><span class="p">)</span><span 
class="o">/</span><span class="n">SampleEntities</span><span 
class="p">.</span><span class="n">CreateOrder</span>
+  <span class="p">{</span>
+    &quot;<span class="n">quantity</span>&quot;<span class="p">:</span> 2<span 
class="p">,</span>
+    &quot;<span class="n">discountCode</span>&quot;<span class="p">:</span> 
&quot;<span class="n">BLACKFRIDAY</span>&quot;
+  <span class="p">}</span>
 </pre></div>
 
 
-<p>As you read in the definition, actions can have side effects (modifying the 
data) but cannot be composed like functions.</p>
 <h2 id="preparation">Preparation<a class="headerlink" href="#preparation" 
title="Permanent link">&para;</a></h2>
-<p>You should read the previous tutorials first to have an idea how to read 
entities and entity collections. In addition the following code is based on the 
write tutorial merged with the navigation tutorial.</p>
+<p>You should read the previous tutorials first to have an idea how to read 
entities and entity collections. </p>
 <p>As a shortcut you should checkout the prepared tutorial project in the <a 
href="https://git-wip-us.apache.org/repos/asf/olingo-odata4";>git repository</a> 
in folder /samples/tutorials/p9_action_preparation.</p>
 <p>Afterwards do a Deploy and run: it should be working. At this state you can 
perform CRUD operations and do navigations between products and categories.</p>
 <h2 id="implementation">Implementation<a class="headerlink" 
href="#implementation" title="Permanent link">&para;</a></h2>
-<p>We use the given data model you are familiar with. To keep things simple we 
implement one function import and one action import.</p>
-<p><strong>Function Import: CountCategories</strong>  <br />
-This function takes a mandatory parameter “<em>Amount</em>”. The function 
returns a collection of categories with the very same number of related 
products.</p>
-<p>After finishing the implementation the definition of the function should 
look like this:</p>
-<div class="codehilite"><pre><span class="nt">&lt;Function</span> <span 
class="na">Name=</span><span class="s">&quot;CountCategories&quot;</span><span 
class="nt">&gt;</span>
-      <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;Amount&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.Int32&quot;</span> <span class="na">Nullable=</span><span 
class="s">&quot;false&quot;</span><span class="nt">/&gt;</span>
-      <span class="nt">&lt;ReturnType</span> <span 
class="na">Type=</span><span 
class="s">&quot;Collection(OData.Demo.Category)&quot;</span><span 
class="nt">/&gt;</span>
-<span class="nt">&lt;/Function&gt;</span>
+<p>We use the given data model you are familiar with. To keep things simple we 
implement one bound action.</p>
+<p><strong>Bound Action that returns a collection of entities: 
DiscountProducts</strong>  <br />
+This action takes bound parameter “<em>ParamCategory</em>” and an 
additional parameter “<em>Amount</em>”. The action updates the price of all 
products related to categories by applying the discount amount.</p>
+<p>After finishing the implementation the definition of the action should be 
like this:</p>
+<div class="codehilite"><pre><span class="nt">&lt;Action</span> <span 
class="na">Name=</span><span class="s">&quot;DiscountProducts&quot;</span> 
<span class="na">IsBound=</span><span class="s">&quot;true&quot;</span><span 
class="nt">&gt;</span>
+  <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;ParamCategory&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Collection(OData.Demo.Category)&quot;</span><span 
class="nt">/&gt;</span>
+  <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;Amount&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.Int32&quot;</span><span class="nt">/&gt;</span>
+  <span class="nt">&lt;ReturnType</span> <span class="na">Type=</span><span 
class="s">&quot;Collection(OData.Demo.Product)&quot;</span><span 
class="nt">/&gt;</span>
+<span class="nt">&lt;/Action&gt;</span>
 </pre></div>
 
 
-<p>As described in the previous tutorials, the type of the response determines 
which processor interface will be called by the Olingo library. It is 
<strong>important to know, that functions are dispatched to the traditional 
processor interfaces</strong>.
-That means there are no special "FunctionProcessors". In our case, the 
function returns a collection of Categories. So we have to extend the 
<code>DemoEntityCollectionProcessor</code>. As you will see it is possible to 
address a single entity by its  key. So we have to extend the 
<code>DemoEntityProcessor</code> as well to handle requests which responds a 
single entity.</p>
-<p><strong>Action Import: Reset</strong>  <br />
-This action takes an optional parameter “<em>Amount</em>”. The actions 
resets the whole data of the service and creates  <em># of Amount</em> products 
with the related categories.</p>
-<p>After finishing the implementation the definition of the action should be 
like this:</p>
-<div class="codehilite"><pre><span class="nt">&lt;Action</span> <span 
class="na">Name=</span><span class="s">&quot;Reset&quot;</span> <span 
class="na">IsBound=</span><span class="s">&quot;false&quot;</span><span 
class="nt">&gt;</span>
-  <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;Amount&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.Int32&quot;</span><span class="nt">/&gt;</span>
+<p><strong>Bound Action that returns an entity: DiscountProduct</strong></p>
+<p>This action takes bound parameter “<em>ParamCategory</em>” and an 
additional parameter “<em>Amount</em>”. The actions updates the price of a 
specific products related to a category by applying the discount amount.
+After finishing the implementation the definition of the action should be like 
this:</p>
+<div class="codehilite"><pre><span class="nt">&lt;Action</span> <span 
class="na">Name=</span><span class="s">&quot;DiscountProduct&quot;</span> <span 
class="na">IsBound=</span><span class="s">&quot;true&quot;</span><span 
class="nt">&gt;</span>
+   <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;ParamCategory&quot;</span> <span class="na">Type=</span><span 
class="s">”OData.Demo.Category&quot;/</span><span class="nt">&gt;</span>
+   <span class="nt">&lt;Parameter</span> <span class="na">Name=</span><span 
class="s">&quot;Amount&quot;</span> <span class="na">Type=</span><span 
class="s">&quot;Edm.Int32&quot;</span><span class="nt">/&gt;</span>
+   <span class="nt">&lt;ReturnType</span> <span class="na">Type=</span><span 
class="s">&quot; OData.Demo.Product&quot;</span><span class="nt">/&gt;</span>
 <span class="nt">&lt;/Action&gt;</span>
 </pre></div>
 
@@ -236,343 +212,167 @@ This action takes an optional parameter
 <ul>
 <li>Extend the Metadata model</li>
 <li>Extend the data store</li>
-<li>Extend the entity collection and the entity processor to handle function 
imports</li>
 <li>Implement an action processor</li>
 </ul>
 <h3 id="extend-the-metadata-model">Extend the Metadata model<a 
class="headerlink" href="#extend-the-metadata-model" title="Permanent 
link">&para;</a></h3>
-<p>Create the following constants in the DemoEdmProvider. These constants are 
used to address the operations.</p>
-<div class="codehilite"><pre><span class="c1">// Action</span>
-<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">ACTION_RESET</span> <span class="o">=</span> <span 
class="s">&quot;Reset&quot;</span><span class="o">;</span>
-<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">FullQualifiedName</span> <span 
class="n">ACTION_RESET_FQN</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">FullQualifiedName</span><span 
class="o">(</span><span class="n">NAMESPACE</span><span class="o">,</span> 
<span class="n">ACTION_RESET</span><span class="o">);</span>
-
-<span class="c1">// Function</span>
-<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">FUNCTION_COUNT_CATEGORIES</span> <span class="o">=</span> <span 
class="s">&quot;CountCategories&quot;</span><span class="o">;</span>
-<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">FullQualifiedName</span> <span 
class="n">FUNCTION_COUNT_CATEGORIES_FQN</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">FullQualifiedName</span><span 
class="o">(</span><span class="n">NAMESPACE</span><span class="o">,</span> 
<span class="n">FUNCTION_COUNT_CATEGORIES</span><span class="o">);</span>
+<p>Create the following constants in the DemoEdmProvider. These constants are 
used to address the actions.</p>
+<div class="codehilite"><pre><span class="c1">//Bound Action</span>
+<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">ACTION_PROVIDE_DISCOUNT</span> <span class="o">=</span> <span 
class="s">&quot;DiscountProducts&quot;</span><span class="o">;</span>
+<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">FullQualifiedName</span> <span 
class="n">ACTION_PROVIDE_DISCOUNT_FQN</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">FullQualifiedName</span><span 
class="o">(</span><span class="n">NAMESPACE</span><span class="o">,</span> 
<span class="n">ACTION_PROVIDE_DISCOUNT</span><span class="o">);</span>
+
+<span class="c1">//Bound Action</span>
+<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT</span> <span class="o">=</span> 
<span class="s">&quot;DiscountProduct&quot;</span><span class="o">;</span>
+<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">FullQualifiedName</span> <span 
class="n">ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT_FQN</span> <span 
class="o">=</span> <span class="k">new</span> <span 
class="n">FullQualifiedName</span><span class="o">(</span><span 
class="n">NAMESPACE</span><span class="o">,</span> <span 
class="n">ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT</span><span class="o">);</span>
 
-<span class="c1">// Function/Action Parameters</span>
+<span class="c1">//Action Parameters</span>
 <span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">PARAMETER_AMOUNT</span> <span class="o">=</span> <span 
class="s">&quot;Amount&quot;</span><span class="o">;</span>
+
+<span class="c1">//Bound Action Binding Parameter</span>
+<span class="kd">public</span> <span class="kd">static</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">PARAMETER_CATEGORY</span> <span class="o">=</span> <span 
class="s">&quot;ParamCategory&quot;</span><span class="o">;</span>
 </pre></div>
 
 
 <p>The way to announce the operations is very similar to announcing 
EntityTypes. We have to override some methods. Those methods provide the 
definition of the Edm elements. We need methods for:</p>
 <ul>
 <li>Actions</li>
-<li>Functions</li>
-<li>Action Imports</li>
-<li>Function Imports</li>
 </ul>
-<p>The code is simple and straight forward. First, we check which function we 
have to return. Then, a list of parameters and the return type are created. At 
the end all parts are fit together and get returned as new 
<code>CsdlFunction</code> Object.</p>
-<div class="codehilite"><pre><span class="nd">@Override</span>
-<span class="kd">public</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">CsdlFunction</span><span 
class="o">&gt;</span> <span class="n">getFunctions</span><span 
class="o">(</span><span class="kd">final</span> <span 
class="n">FullQualifiedName</span> <span class="n">functionName</span><span 
class="o">)</span> <span class="o">{</span>
-  <span class="k">if</span> <span class="o">(</span><span 
class="n">functionName</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">FUNCTION_COUNT_CATEGORIES_FQN</span><span class="o">))</span> <span 
class="o">{</span>
-    <span class="c1">// It is allowed to overload functions, so we have to 
provide a list of functions for each function name</span>
-    <span class="kd">final</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">CsdlFunction</span><span 
class="o">&gt;</span> <span class="n">functions</span> <span class="o">=</span> 
<span class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">CsdlFunction</span><span 
class="o">&gt;();</span>
-
-    <span class="c1">// Create the parameter for the function</span>
-    <span class="kd">final</span> <span class="n">CsdlParameter</span> <span 
class="n">parameterAmount</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">CsdlParameter</span><span 
class="o">();</span>
-    <span class="n">parameterAmount</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">PARAMETER_AMOUNT</span><span class="o">);</span>
-    <span class="n">parameterAmount</span><span class="o">.</span><span 
class="na">setNullable</span><span class="o">(</span><span 
class="kc">false</span><span class="o">);</span>
-    <span class="n">parameterAmount</span><span class="o">.</span><span 
class="na">setType</span><span class="o">(</span><span 
class="n">EdmPrimitiveTypeKind</span><span class="o">.</span><span 
class="na">Int32</span><span class="o">.</span><span 
class="na">getFullQualifiedName</span><span class="o">());</span>
-
-    <span class="c1">// Create the return type of the function</span>
-    <span class="kd">final</span> <span class="n">CsdlReturnType</span> <span 
class="n">returnType</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">CsdlReturnType</span><span class="o">();</span>
-    <span class="n">returnType</span><span class="o">.</span><span 
class="na">setCollection</span><span class="o">(</span><span 
class="kc">true</span><span class="o">);</span>
-    <span class="n">returnType</span><span class="o">.</span><span 
class="na">setType</span><span class="o">(</span><span 
class="n">ET_CATEGORY_FQN</span><span class="o">);</span>
-
-    <span class="c1">// Create the function</span>
-    <span class="kd">final</span> <span class="n">CsdlFunction</span> <span 
class="n">function</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">CsdlFunction</span><span class="o">();</span>
-    <span class="n">function</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">FUNCTION_COUNT_CATEGORIES_FQN</span><span class="o">.</span><span 
class="na">getName</span><span class="o">())</span>
-        <span class="o">.</span><span class="na">setParameters</span><span 
class="o">(</span><span class="n">Arrays</span><span class="o">.</span><span 
class="na">asList</span><span class="o">(</span><span 
class="n">parameterAmount</span><span class="o">))</span>
-        <span class="o">.</span><span class="na">setReturnType</span><span 
class="o">(</span><span class="n">returnType</span><span class="o">);</span>
-    <span class="n">functions</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">function</span><span class="o">);</span>
-
-    <span class="k">return</span> <span class="n">functions</span><span 
class="o">;</span>
-  <span class="o">}</span>
-
-  <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
-<span class="o">}</span>
-</pre></div>
-
-
-<p>We have created the function itself. To express that function can be called 
statically we have to override the method <code>getFunctionImport()</code>.</p>
-<div class="codehilite"><pre><span class="nd">@Override</span>
-<span class="kd">public</span> <span class="n">CsdlFunctionImport</span> <span 
class="nf">getFunctionImport</span><span class="o">(</span><span 
class="n">FullQualifiedName</span> <span class="n">entityContainer</span><span 
class="o">,</span> <span class="n">String</span> <span 
class="n">functionImportName</span><span class="o">)</span> <span 
class="o">{</span>
-  <span class="k">if</span><span class="o">(</span><span 
class="n">entityContainer</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">CONTAINER</span><span class="o">))</span> <span class="o">{</span>
-    <span class="k">if</span><span class="o">(</span><span 
class="n">functionImportName</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">FUNCTION_COUNT_CATEGORIES_FQN</span><span class="o">.</span><span 
class="na">getName</span><span class="o">()))</span> <span class="o">{</span>
-      <span class="k">return</span> <span class="k">new</span> <span 
class="nf">CsdlFunctionImport</span><span class="o">()</span>
-                <span class="o">.</span><span class="na">setName</span><span 
class="o">(</span><span class="n">functionImportName</span><span 
class="o">)</span>
-                <span class="o">.</span><span 
class="na">setFunction</span><span class="o">(</span><span 
class="n">FUNCTION_COUNT_CATEGORIES_FQN</span><span class="o">)</span>
-                <span class="o">.</span><span 
class="na">setEntitySet</span><span class="o">(</span><span 
class="n">ES_CATEGORIES_NAME</span><span class="o">)</span>
-                <span class="o">.</span><span 
class="na">setIncludeInServiceDocument</span><span class="o">(</span><span 
class="kc">true</span><span class="o">);</span>
-    <span class="o">}</span>
-  <span class="o">}</span>
-
-  <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
-<span class="o">}</span>
-</pre></div>
-
-
-<p>To define the actions and the action imports the <code>getActions()</code> 
and <code>getActionImport()</code> methods have to be overriden and the 
necessary code is quite similar to the functions sample above:</p>
-<div class="codehilite"><pre><span class="nd">@Override</span>
-<span class="kd">public</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">CsdlAction</span><span 
class="o">&gt;</span> <span class="n">getActions</span><span 
class="o">(</span><span class="kd">final</span> <span 
class="n">FullQualifiedName</span> <span class="n">actionName</span><span 
class="o">)</span> <span class="o">{</span>
-  <span class="k">if</span><span class="o">(</span><span 
class="n">actionName</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">ACTION_RESET_FQN</span><span class="o">))</span> <span 
class="o">{</span>
-    <span class="c1">// It is allowed to overload actions, so we have to 
provide a list of Actions for each action name</span>
+<p>The code is simple and straight forward. We need to create a list of 
parameters of which the first parameter should be the binding parameter, then 
create a return type. At the end all parts are fit together and get returned as 
new CsdlAction Object.</p>
+<div class="codehilite"><pre>    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">CsdlAction</span><span 
class="o">&gt;</span> <span class="n">getActions</span><span 
class="o">(</span><span class="kd">final</span> <span 
class="n">FullQualifiedName</span> <span class="n">actionName</span><span 
class="o">)</span> <span class="o">{</span>
+   <span class="c1">// It is allowed to overload actions, so we have to 
provide a list of Actions for each action name</span>
     <span class="kd">final</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">CsdlAction</span><span 
class="o">&gt;</span> <span class="n">actions</span> <span class="o">=</span> 
<span class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">CsdlAction</span><span 
class="o">&gt;();</span>
 
-    <span class="c1">// Create parameters</span>
-    <span class="kd">final</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">CsdlParameter</span><span 
class="o">&gt;</span> <span class="n">parameters</span> <span 
class="o">=</span> <span class="k">new</span> <span 
class="n">ArrayList</span><span class="o">&lt;</span><span 
class="n">CsdlParameter</span><span class="o">&gt;();</span>
-    <span class="kd">final</span> <span class="n">CsdlParameter</span> <span 
class="n">parameter</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">CsdlParameter</span><span class="o">();</span>
-    <span class="n">parameter</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">PARAMETER_AMOUNT</span><span class="o">);</span>
-    <span class="n">parameter</span><span class="o">.</span><span 
class="na">setType</span><span class="o">(</span><span 
class="n">EdmPrimitiveTypeKind</span><span class="o">.</span><span 
class="na">Int32</span><span class="o">.</span><span 
class="na">getFullQualifiedName</span><span class="o">());</span>
-    <span class="n">parameters</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">parameter</span><span class="o">);</span>
-
-    <span class="c1">// Create the Csdl Action</span>
-    <span class="kd">final</span> <span class="n">CsdlAction</span> <span 
class="n">action</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">CsdlAction</span><span class="o">();</span>
-    <span class="n">action</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">ACTION_RESET_FQN</span><span class="o">.</span><span 
class="na">getName</span><span class="o">());</span>
-    <span class="n">action</span><span class="o">.</span><span 
class="na">setParameters</span><span class="o">(</span><span 
class="n">parameters</span><span class="o">);</span>
-    <span class="n">actions</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span class="n">action</span><span 
class="o">);</span>
+    <span class="k">if</span> <span class="o">(</span><span 
class="n">actionName</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">ACTION_PROVIDE_DISCOUNT_FQN</span><span class="o">))</span> <span 
class="o">{</span>
+      <span class="c1">// Create parameters</span>
+      <span class="kd">final</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">CsdlParameter</span><span 
class="o">&gt;</span> <span class="n">parameters</span> <span 
class="o">=</span> <span class="k">new</span> <span 
class="n">ArrayList</span><span class="o">&lt;</span><span 
class="n">CsdlParameter</span><span class="o">&gt;();</span>
+      <span class="n">CsdlParameter</span> <span class="n">parameter</span> 
<span class="o">=</span> <span class="k">new</span> <span 
class="n">CsdlParameter</span><span class="o">();</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">PARAMETER_CATEGORY</span><span class="o">);</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setType</span><span class="o">(</span><span 
class="n">ET_CATEGORY_FQN</span><span class="o">);</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setCollection</span><span class="o">(</span><span 
class="kc">true</span><span class="o">);</span>
+      <span class="n">parameters</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">parameter</span><span class="o">);</span>
+      <span class="n">parameter</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">CsdlParameter</span><span 
class="o">();</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">PARAMETER_AMOUNT</span><span class="o">);</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setType</span><span class="o">(</span><span 
class="n">EdmPrimitiveTypeKind</span><span class="o">.</span><span 
class="na">Int32</span><span class="o">.</span><span 
class="na">getFullQualifiedName</span><span class="o">());</span>
+      <span class="n">parameters</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">parameter</span><span class="o">);</span>
+
+      <span class="c1">// Create the Csdl Action</span>
+      <span class="kd">final</span> <span class="n">CsdlAction</span> <span 
class="n">action</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">CsdlAction</span><span class="o">();</span>
+      <span class="n">action</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">ACTION_PROVIDE_DISCOUNT_FQN</span><span class="o">.</span><span 
class="na">getName</span><span class="o">());</span>
+      <span class="n">action</span><span class="o">.</span><span 
class="na">setBound</span><span class="o">(</span><span 
class="kc">true</span><span class="o">);</span>
+      <span class="n">action</span><span class="o">.</span><span 
class="na">setParameters</span><span class="o">(</span><span 
class="n">parameters</span><span class="o">);</span>
+      <span class="n">action</span><span class="o">.</span><span 
class="na">setReturnType</span><span class="o">(</span><span 
class="k">new</span> <span class="n">CsdlReturnType</span><span 
class="o">().</span><span class="na">setType</span><span 
class="o">(</span><span class="n">ET_PRODUCT_FQN</span><span 
class="o">).</span><span class="na">setCollection</span><span 
class="o">(</span><span class="kc">true</span><span class="o">));</span>
+      <span class="n">actions</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span class="n">action</span><span 
class="o">);</span>
+
+      <span class="k">return</span> <span class="n">actions</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">actionName</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT_FQN</span><span 
class="o">))</span> <span class="o">{</span>
+      <span class="c1">// Create parameters</span>
+      <span class="kd">final</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">CsdlParameter</span><span 
class="o">&gt;</span> <span class="n">parameters</span> <span 
class="o">=</span> <span class="k">new</span> <span 
class="n">ArrayList</span><span class="o">&lt;</span><span 
class="n">CsdlParameter</span><span class="o">&gt;();</span>
+      <span class="n">CsdlParameter</span> <span class="n">parameter</span> 
<span class="o">=</span> <span class="k">new</span> <span 
class="n">CsdlParameter</span><span class="o">();</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">PARAMETER_CATEGORY</span><span class="o">);</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setType</span><span class="o">(</span><span 
class="n">ET_CATEGORY_FQN</span><span class="o">);</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setCollection</span><span class="o">(</span><span 
class="kc">false</span><span class="o">);</span>
+      <span class="n">parameters</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">parameter</span><span class="o">);</span>
+      <span class="n">parameter</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">CsdlParameter</span><span 
class="o">();</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">PARAMETER_AMOUNT</span><span class="o">);</span>
+      <span class="n">parameter</span><span class="o">.</span><span 
class="na">setType</span><span class="o">(</span><span 
class="n">EdmPrimitiveTypeKind</span><span class="o">.</span><span 
class="na">Int32</span><span class="o">.</span><span 
class="na">getFullQualifiedName</span><span class="o">());</span>
+      <span class="n">parameters</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">parameter</span><span class="o">);</span>
+
+      <span class="c1">// Create the Csdl Action</span>
+      <span class="kd">final</span> <span class="n">CsdlAction</span> <span 
class="n">action</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">CsdlAction</span><span class="o">();</span>
+      <span class="n">action</span><span class="o">.</span><span 
class="na">setName</span><span class="o">(</span><span 
class="n">ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT_FQN</span><span 
class="o">.</span><span class="na">getName</span><span class="o">());</span>
+      <span class="n">action</span><span class="o">.</span><span 
class="na">setBound</span><span class="o">(</span><span 
class="kc">true</span><span class="o">);</span>
+      <span class="n">action</span><span class="o">.</span><span 
class="na">setParameters</span><span class="o">(</span><span 
class="n">parameters</span><span class="o">);</span>
+      <span class="n">action</span><span class="o">.</span><span 
class="na">setReturnType</span><span class="o">(</span><span 
class="k">new</span> <span class="n">CsdlReturnType</span><span 
class="o">().</span><span class="na">setType</span><span 
class="o">(</span><span class="n">ET_PRODUCT_FQN</span><span 
class="o">).</span><span class="na">setCollection</span><span 
class="o">(</span><span class="kc">false</span><span class="o">));</span>
+      <span class="n">actions</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span class="n">action</span><span 
class="o">);</span>
 
-    <span class="k">return</span> <span class="n">actions</span><span 
class="o">;</span>
-  <span class="o">}</span>
-
-  <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
-<span class="o">}</span>
-
-<span class="nd">@Override</span>
-<span class="kd">public</span> <span class="n">CsdlActionImport</span> <span 
class="nf">getActionImport</span><span class="o">(</span><span 
class="kd">final</span> <span class="n">FullQualifiedName</span> <span 
class="n">entityContainer</span><span class="o">,</span> <span 
class="kd">final</span> <span class="n">String</span> <span 
class="n">actionImportName</span><span class="o">)</span> <span 
class="o">{</span>
-  <span class="k">if</span><span class="o">(</span><span 
class="n">entityContainer</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">CONTAINER</span><span class="o">))</span> <span class="o">{</span>
-    <span class="k">if</span><span class="o">(</span><span 
class="n">actionImportName</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">ACTION_RESET_FQN</span><span class="o">.</span><span 
class="na">getName</span><span class="o">()))</span> <span class="o">{</span>
-      <span class="k">return</span> <span class="k">new</span> <span 
class="nf">CsdlActionImport</span><span class="o">()</span>
-              <span class="o">.</span><span class="na">setName</span><span 
class="o">(</span><span class="n">actionImportName</span><span 
class="o">)</span>
-              <span class="o">.</span><span class="na">setAction</span><span 
class="o">(</span><span class="n">ACTION_RESET_FQN</span><span 
class="o">);</span>
+      <span class="k">return</span> <span class="n">actions</span><span 
class="o">;</span>
     <span class="o">}</span>
-  <span class="o">}</span>
 
-  <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
-<span class="o">}</span>
+    <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
+  <span class="o">}</span>
 </pre></div>
 
 
-<p>Finally we have to announce these operations to the schema and the entity 
container.
-Add the following lines to the method <code>getSchemas()</code>:</p>
+<p>Finally we have to announce these operations to the schema. Add the 
following lines to the method getSchemas():</p>
 <div class="codehilite"><pre><span class="c1">// add actions</span>
 <span class="n">List</span><span class="o">&lt;</span><span 
class="n">CsdlAction</span><span class="o">&gt;</span> <span 
class="n">actions</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">ArrayList</span><span class="o">&lt;</span><span 
class="n">CsdlAction</span><span class="o">&gt;();</span>
-<span class="n">actions</span><span class="o">.</span><span 
class="na">addAll</span><span class="o">(</span><span 
class="n">getActions</span><span class="o">(</span><span 
class="n">ACTION_RESET_FQN</span><span class="o">));</span>
+<span class="n">actions</span><span class="o">.</span><span 
class="na">addAll</span><span class="o">(</span><span 
class="n">getActions</span><span class="o">(</span><span 
class="n">ACTION_PROVIDE_DISCOUNT_FQN</span><span class="o">));</span>
+<span class="n">actions</span><span class="o">.</span><span 
class="na">addAll</span><span class="o">(</span><span 
class="n">getActions</span><span class="o">(</span><span 
class="n">ACTION_PROVIDE_DISCOUNT_FOR_PRODUCT_FQN</span><span 
class="o">));</span>
 <span class="n">schema</span><span class="o">.</span><span 
class="na">setActions</span><span class="o">(</span><span 
class="n">actions</span><span class="o">);</span>
-
-<span class="c1">// add functions</span>
-<span class="n">List</span><span class="o">&lt;</span><span 
class="n">CsdlFunction</span><span class="o">&gt;</span> <span 
class="n">functions</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">ArrayList</span><span class="o">&lt;</span><span 
class="n">CsdlFunction</span><span class="o">&gt;();</span>
-<span class="n">functions</span><span class="o">.</span><span 
class="na">addAll</span><span class="o">(</span><span 
class="n">getFunctions</span><span class="o">(</span><span 
class="n">FUNCTION_COUNT_CATEGORIES_FQN</span><span class="o">));</span>
-<span class="n">schema</span><span class="o">.</span><span 
class="na">setFunctions</span><span class="o">(</span><span 
class="n">functions</span><span class="o">);</span>
-</pre></div>
-
-
-<p>Also add the following lines to the method 
<code>getEntityContainer()</code></p>
-<div class="codehilite"><pre><span class="c1">// Create function imports</span>
-<span class="n">List</span><span class="o">&lt;</span><span 
class="n">CsdlFunctionImport</span><span class="o">&gt;</span> <span 
class="n">functionImports</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">CsdlFunctionImport</span><span 
class="o">&gt;();</span>
-<span class="n">functionImports</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">getFunctionImport</span><span class="o">(</span><span 
class="n">CONTAINER</span><span class="o">,</span> <span 
class="n">FUNCTION_COUNT_CATEGORIES</span><span class="o">));</span>
-
-<span class="c1">// Create action imports</span>
-<span class="n">List</span><span class="o">&lt;</span><span 
class="n">CsdlActionImport</span><span class="o">&gt;</span> <span 
class="n">actionImports</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">CsdlActionImport</span><span 
class="o">&gt;();</span>
-<span class="n">actionImports</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">getActionImport</span><span class="o">(</span><span 
class="n">CONTAINER</span><span class="o">,</span> <span 
class="n">ACTION_RESET</span><span class="o">));</span>
-
-<span class="n">entityContainer</span><span class="o">.</span><span 
class="na">setFunctionImports</span><span class="o">(</span><span 
class="n">functionImports</span><span class="o">);</span>
-<span class="n">entityContainer</span><span class="o">.</span><span 
class="na">setActionImports</span><span class="o">(</span><span 
class="n">actionImports</span><span class="o">);</span>
 </pre></div>
 
 
 <h3 id="extend-the-data-store">Extend the data store<a class="headerlink" 
href="#extend-the-data-store" title="Permanent link">&para;</a></h3>
-<p>We need two methods in the data store to read the function import 
<code>CountCategories</code>.</p>
-<p>The first method returns a collection of entites and the second returns a 
single entity of this collection.</p>
-<div class="codehilite"><pre><span class="kd">public</span> <span 
class="n">EntityCollection</span> <span 
class="nf">readFunctionImportCollection</span><span class="o">(</span><span 
class="kd">final</span> <span class="n">UriResourceFunction</span> <span 
class="n">uriResourceFunction</span><span class="o">,</span> <span 
class="kd">final</span> <span class="n">ServiceMetadata</span> <span 
class="n">serviceMetadata</span><span class="o">)</span> <span 
class="kd">throws</span> <span class="n">ODataApplicationException</span> <span 
class="o">{</span>
-
-  <span class="k">if</span><span class="o">(</span><span 
class="n">DemoEdmProvider</span><span class="o">.</span><span 
class="na">FUNCTION_COUNT_CATEGORIES</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">uriResourceFunction</span><span class="o">.</span><span 
class="na">getFunctionImport</span><span class="o">().</span><span 
class="na">getName</span><span class="o">()))</span> <span class="o">{</span>
-    <span class="c1">// Get the parameter of the function</span>
-    <span class="kd">final</span> <span class="n">UriParameter</span> <span 
class="n">parameterAmount</span> <span class="o">=</span> <span 
class="n">uriResourceFunction</span><span class="o">.</span><span 
class="na">getParameters</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="c1">// Try to convert the parameter to an Integer.</span>
-    <span class="c1">// We have to take care, that the type of parameter fits 
to its EDM declaration</span>
-    <span class="kt">int</span> <span class="n">amount</span><span 
class="o">;</span>
-    <span class="k">try</span> <span class="o">{</span>
-      <span class="n">amount</span> <span class="o">=</span> <span 
class="n">Integer</span><span class="o">.</span><span 
class="na">parseInt</span><span class="o">(</span><span 
class="n">parameterAmount</span><span class="o">.</span><span 
class="na">getText</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">&quot;Type of parameter Amount must be Edm.Int32&quot;</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="kd">final</span> <span class="n">EdmEntityType</span> <span 
class="n">productEntityType</span> <span class="o">=</span> <span 
class="n">serviceMetadata</span><span class="o">.</span><span 
class="na">getEdm</span><span class="o">().</span><span 
class="na">getEntityType</span><span class="o">(</span><span 
class="n">DemoEdmProvider</span><span class="o">.</span><span 
class="na">ET_PRODUCT_FQN</span><span class="o">);</span>
-    <span class="kd">final</span> <span class="n">List</span><span 
class="o">&lt;</span><span class="n">Entity</span><span class="o">&gt;</span> 
<span class="n">resultEntityList</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">Entity</span><span class="o">&gt;();</span>
-
-    <span class="c1">// Loop over all categories and check how many products 
are linked</span>
-    <span class="k">for</span><span class="o">(</span><span 
class="kd">final</span> <span class="n">Entity</span> <span 
class="n">category</span> <span class="o">:</span> <span 
class="n">categoryList</span><span class="o">)</span> <span class="o">{</span>
-      <span class="kd">final</span> <span class="n">EntityCollection</span> 
<span class="n">products</span> <span class="o">=</span> <span 
class="n">getRelatedEntityCollection</span><span class="o">(</span><span 
class="n">category</span><span class="o">,</span> <span 
class="n">productEntityType</span><span class="o">);</span>
-      <span class="k">if</span><span class="o">(</span><span 
class="n">products</span><span class="o">.</span><span 
class="na">getEntities</span><span class="o">().</span><span 
class="na">size</span><span class="o">()</span> <span class="o">==</span> <span 
class="n">amount</span><span class="o">)</span> <span class="o">{</span>
-        <span class="n">resultEntityList</span><span class="o">.</span><span 
class="na">add</span><span class="o">(</span><span 
class="n">category</span><span class="o">);</span>
+<p>We need two methods in the data store to read the action DiscountProducts 
and DiscountProduct. The first method returns a collection of entites and 
second method returns a single entity.</p>
+<div class="codehilite"><pre>    <span class="kd">public</span> <span 
class="n">EntityCollection</span> <span 
class="nf">processBoundActionEntityCollection</span><span 
class="o">(</span><span class="n">EdmAction</span> <span 
class="n">action</span><span class="o">,</span> <span class="n">Map</span><span 
class="o">&lt;</span><span class="n">String</span><span class="o">,</span> 
<span class="n">Parameter</span><span class="o">&gt;</span> <span 
class="n">parameters</span><span class="o">)</span> <span class="o">{</span>
+    <span class="n">EntityCollection</span> <span class="n">collection</span> 
<span class="o">=</span> <span class="k">new</span> <span 
class="n">EntityCollection</span><span class="o">();</span>
+    <span class="k">if</span> <span class="o">(</span><span 
class="s">&quot;DiscountProducts&quot;</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">action</span><span class="o">.</span><span 
class="na">getName</span><span class="o">()))</span> <span class="o">{</span>
+      <span class="k">for</span> <span class="o">(</span><span 
class="n">Entity</span> <span class="n">entity</span> <span class="o">:</span> 
<span class="n">categoryList</span><span class="o">)</span> <span 
class="o">{</span>
+        <span class="n">Entity</span> <span class="n">en</span> <span 
class="o">=</span> <span class="n">getRelatedEntity</span><span 
class="o">(</span><span class="n">entity</span><span class="o">,</span> <span 
class="o">(</span><span class="n">EdmEntityType</span><span class="o">)</span> 
<span class="n">action</span><span class="o">.</span><span 
class="na">getReturnType</span><span class="o">().</span><span 
class="na">getType</span><span class="o">());</span>
+        <span class="n">Integer</span> <span class="n">currentValue</span> 
<span class="o">=</span> <span class="o">(</span><span 
class="n">Integer</span><span class="o">)</span><span class="n">en</span><span 
class="o">.</span><span class="na">getProperty</span><span 
class="o">(</span><span class="s">&quot;Price&quot;</span><span 
class="o">).</span><span class="na">asPrimitive</span><span class="o">();</span>
+        <span class="n">Integer</span> <span class="n">newValue</span> <span 
class="o">=</span> <span class="n">currentValue</span> <span class="o">-</span> 
<span class="o">(</span><span class="n">Integer</span><span 
class="o">)</span><span class="n">parameters</span><span 
class="o">.</span><span class="na">get</span><span class="o">(</span><span 
class="s">&quot;Amount&quot;</span><span class="o">).</span><span 
class="na">asPrimitive</span><span class="o">();</span>
+        <span class="n">en</span><span class="o">.</span><span 
class="na">getProperty</span><span class="o">(</span><span 
class="s">&quot;Price&quot;</span><span class="o">).</span><span 
class="na">setValue</span><span class="o">(</span><span 
class="n">ValueType</span><span class="o">.</span><span 
class="na">PRIMITIVE</span><span class="o">,</span> <span 
class="n">newValue</span><span class="o">);</span>
+        <span class="n">collection</span><span class="o">.</span><span 
class="na">getEntities</span><span class="o">().</span><span 
class="na">add</span><span class="o">(</span><span class="n">en</span><span 
class="o">);</span>
       <span class="o">}</span>
     <span class="o">}</span>
-
-    <span class="kd">final</span> <span class="n">EntityCollection</span> 
<span class="n">resultCollection</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">EntityCollection</span><span 
class="o">();</span>
-    <span class="n">resultCollection</span><span class="o">.</span><span 
class="na">getEntities</span><span class="o">().</span><span 
class="na">addAll</span><span class="o">(</span><span 
class="n">resultEntityList</span><span class="o">);</span>
-    <span class="k">return</span> <span class="n">resultCollection</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">&quot;Function not implemented&quot;</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">ROOT</span><span class="o">);</span>
+    <span class="k">return</span> <span class="n">collection</span><span 
class="o">;</span>
   <span class="o">}</span>
-<span class="o">}</span>
-
-<span class="kd">public</span> <span class="n">Entity</span> <span 
class="nf">readFunctionImportEntity</span><span class="o">(</span><span 
class="kd">final</span> <span class="n">UriResourceFunction</span> <span 
class="n">uriResourceFunction</span><span class="o">,</span>
-  <span class="kd">final</span> <span class="n">ServiceMetadata</span> <span 
class="n">serviceMetadata</span><span class="o">)</span> <span 
class="kd">throws</span> <span class="n">ODataApplicationException</span> <span 
class="o">{</span>
-
-  <span class="kd">final</span> <span class="n">EntityCollection</span> <span 
class="n">entityCollection</span> <span class="o">=</span> <span 
class="n">readFunctionImportCollection</span><span class="o">(</span><span 
class="n">uriResourceFunction</span><span class="o">,</span> <span 
class="n">serviceMetadata</span><span class="o">);</span>
-  <span class="kd">final</span> <span class="n">EdmEntityType</span> <span 
class="n">edmEntityType</span> <span class="o">=</span> <span 
class="o">(</span><span class="n">EdmEntityType</span><span class="o">)</span> 
<span class="n">uriResourceFunction</span><span class="o">.</span><span 
class="na">getFunction</span><span class="o">().</span><span 
class="na">getReturnType</span><span class="o">().</span><span 
class="na">getType</span><span class="o">();</span>
-
-  <span class="k">return</span> <span class="n">Util</span><span 
class="o">.</span><span class="na">findEntity</span><span 
class="o">(</span><span class="n">edmEntityType</span><span class="o">,</span> 
<span class="n">entityCollection</span><span class="o">,</span> <span 
class="n">uriResourceFunction</span><span class="o">.</span><span 
class="na">getKeyPredicates</span><span class="o">());</span>
-<span class="o">}</span>
-</pre></div>
 
-
-<p>We also create two methods to reset the data of our service.</p>
-<div class="codehilite"><pre><span class="kd">public</span> <span 
class="kt">void</span> <span class="nf">resetDataSet</span><span 
class="o">(</span><span class="kd">final</span> <span class="kt">int</span> 
<span class="n">amount</span><span class="o">)</span> <span class="o">{</span>
-  <span class="c1">// Replace the old lists with empty ones</span>
-  <span class="n">productList</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">Entity</span><span class="o">&gt;();</span>
-  <span class="n">categoryList</span> <span class="o">=</span> <span 
class="k">new</span> <span class="n">ArrayList</span><span 
class="o">&lt;</span><span class="n">Entity</span><span class="o">&gt;();</span>
-
-  <span class="c1">// Create new sample data</span>
-  <span class="n">initProductSampleData</span><span class="o">();</span>
-  <span class="n">initCategorySampleData</span><span class="o">();</span>
-
-  <span class="c1">// Truncate the lists</span>
-  <span class="k">if</span><span class="o">(</span><span 
class="n">amount</span> <span class="o">&lt;</span> <span 
class="n">productList</span><span class="o">.</span><span 
class="na">size</span><span class="o">())</span> <span class="o">{</span>
-    <span class="n">productList</span> <span class="o">=</span> <span 
class="n">productList</span><span class="o">.</span><span 
class="na">subList</span><span class="o">(</span><span class="mi">0</span><span 
class="o">,</span> <span class="n">amount</span><span class="o">);</span>
-    <span class="c1">// Products 0, 1 are linked to category 0</span>
-    <span class="c1">// Products 2, 3 are linked to category 1</span>
-    <span class="c1">// Products 4, 5 are linked to category 2</span>
-    <span class="n">categoryList</span> <span class="o">=</span> <span 
class="n">categoryList</span><span class="o">.</span><span 
class="na">subList</span><span class="o">(</span><span class="mi">0</span><span 
class="o">,</span> <span class="o">(</span><span class="n">amount</span> <span 
class="o">/</span> <span class="mi">2</span><span class="o">)</span> <span 
class="o">+</span> <span class="mi">1</span><span class="o">);</span>
-  <span class="o">}</span>
-<span class="o">}</span>
-
-<span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">resetDataSet</span><span class="o">()</span> <span class="o">{</span>
-  <span class="n">resetDataSet</span><span class="o">(</span><span 
class="n">Integer</span><span class="o">.</span><span 
class="na">MAX_VALUE</span><span class="o">);</span>
-<span class="o">}</span>
-</pre></div>
-
-
-<h3 
id="extend-the-entity-collection-and-the-entity-processor-to-handle-function-imports">Extend
 the entity collection and the entity processor to handle function imports<a 
class="headerlink" 
href="#extend-the-entity-collection-and-the-entity-processor-to-handle-function-imports"
 title="Permanent link">&para;</a></h3>
-<p>We start with the entity collection processor 
<code>DemoEntityCollectionProcessor</code>.
-To keep things simple, the first steps is to distinguish between entity 
collections and function imports.
-A cleverer implementation can handle both cases in one method to avoid 
duplicated code.</p>
-<p>The recent implementation of the <code>readEntityCollection()</code> has 
been moved to <code>readEntityCollectionInternal()</code></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> <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="kd">final</span> <span class="n">UriResource</span> <span 
class="n">firstResourceSegment</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="na">get</span><span class="o">(</span><span class="mi">0</span><span 
class="o">);</span>
-
-  <span class="k">if</span><span class="o">(</span><span 
class="n">firstResourceSegment</span> <span class="k">instanceof</span> <span 
class="n">UriResourceEntitySet</span><span class="o">)</span> <span 
class="o">{</span>
-    <span class="n">readEntityCollectionInternal</span><span 
class="o">(</span><span class="n">request</span><span class="o">,</span> <span 
class="n">response</span><span class="o">,</span> <span 
class="n">uriInfo</span><span class="o">,</span> <span 
class="n">responseFormat</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">firstResourceSegment</span> <span class="k">instanceof</span> <span 
class="n">UriResourceFunction</span><span class="o">)</span> <span 
class="o">{</span>
-    <span class="n">readFunctionImportCollection</span><span 
class="o">(</span><span class="n">request</span><span class="o">,</span> <span 
class="n">response</span><span class="o">,</span> <span 
class="n">uriInfo</span><span class="o">,</span> <span 
class="n">responseFormat</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">&quot;Not implemented&quot;</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>
-</pre></div>
-
-
-<p>Like by reading <em>entity collections</em>, the first step is to analyze 
the URI and then fetch the data (of the function import).</p>
-<div class="codehilite"><pre><span class="kd">private</span> <span 
class="kt">void</span> <span 
class="nf">readFunctionImportCollection</span><span class="o">(</span><span 
class="kd">final</span> <span class="n">ODataRequest</span> <span 
class="n">request</span><span class="o">,</span> <span class="kd">final</span> 
<span class="n">ODataResponse</span> <span class="n">response</span><span 
class="o">,</span>
-  <span class="kd">final</span> <span class="n">UriInfo</span> <span 
class="n">uriInfo</span><span class="o">,</span> <span class="kd">final</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 step: Analyze the URI and fetch the entity 
collection returned by the function import</span>
-  <span class="c1">// Function Imports are always the first segment of the 
resource path</span>
-  <span class="kd">final</span> <span class="n">UriResource</span> <span 
class="n">firstSegment</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="na">get</span><span class="o">(</span><span class="mi">0</span><span 
class="o">);</span>
-
-  <span class="k">if</span><span class="o">(!(</span><span 
class="n">firstSegment</span> <span class="k">instanceof</span> <span 
class="n">UriResourceFunction</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">&quot;Not implemented&quot;</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="kd">public</span> <span class="n">DemoEntityActionResult</span> 
<span class="nf">processBoundActionEntity</span><span class="o">(</span><span 
class="n">EdmAction</span> <span class="n">action</span><span 
class="o">,</span> <span class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">Parameter</span><span class="o">&gt;</span> <span 
class="n">parameters</span><span class="o">,</span>
+      <span class="n">List</span><span class="o">&lt;</span><span 
class="n">UriParameter</span><span class="o">&gt;</span> <span 
class="n">keyParams</span><span class="o">)</span> <span 
class="kd">throws</span> <span class="n">ODataApplicationException</span> <span 
class="o">{</span>
+    <span class="n">DemoEntityActionResult</span> <span 
class="n">result</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">DemoEntityActionResult</span><span class="o">();</span>
+    <span class="k">if</span> <span class="o">(</span><span 
class="s">&quot;DiscountProduct&quot;</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">action</span><span class="o">.</span><span 
class="na">getName</span><span class="o">()))</span> <span class="o">{</span>
+      <span class="k">for</span> <span class="o">(</span><span 
class="n">Entity</span> <span class="n">entity</span> <span class="o">:</span> 
<span class="n">categoryList</span><span class="o">)</span> <span 
class="o">{</span>
+        <span class="n">Entity</span> <span class="n">en</span> <span 
class="o">=</span> <span class="n">getRelatedEntity</span><span 
class="o">(</span><span class="n">entity</span><span class="o">,</span> <span 
class="o">(</span><span class="n">EdmEntityType</span><span class="o">)</span> 
<span class="n">action</span><span class="o">.</span><span 
class="na">getReturnType</span><span class="o">().</span><span 
class="na">getType</span><span class="o">(),</span> <span 
class="n">keyParams</span><span class="o">);</span>
+        <span class="n">Integer</span> <span class="n">currentValue</span> 
<span class="o">=</span> <span class="o">(</span><span 
class="n">Integer</span><span class="o">)</span><span class="n">en</span><span 
class="o">.</span><span class="na">getProperty</span><span 
class="o">(</span><span class="s">&quot;Price&quot;</span><span 
class="o">).</span><span class="na">asPrimitive</span><span class="o">();</span>
+        <span class="n">Integer</span> <span class="n">newValue</span> <span 
class="o">=</span> <span class="n">currentValue</span> <span class="o">-</span> 
<span class="o">(</span><span class="n">Integer</span><span 
class="o">)</span><span class="n">parameters</span><span 
class="o">.</span><span class="na">get</span><span class="o">(</span><span 
class="s">&quot;Amount&quot;</span><span class="o">).</span><span 
class="na">asPrimitive</span><span class="o">();</span>
+        <span class="n">en</span><span class="o">.</span><span 
class="na">getProperty</span><span class="o">(</span><span 
class="s">&quot;Price&quot;</span><span class="o">).</span><span 
class="na">setValue</span><span class="o">(</span><span 
class="n">ValueType</span><span class="o">.</span><span 
class="na">PRIMITIVE</span><span class="o">,</span> <span 
class="n">newValue</span><span class="o">);</span>
+        <span class="n">result</span><span class="o">.</span><span 
class="na">setEntity</span><span class="o">(</span><span 
class="n">en</span><span class="o">);</span>
+        <span class="n">result</span><span class="o">.</span><span 
class="na">setCreated</span><span class="o">(</span><span 
class="kc">true</span><span class="o">);</span>
+        <span class="k">return</span> <span class="n">result</span><span 
class="o">;</span>
+      <span class="o">}</span>
+    <span class="o">}</span>
+    <span class="k">return</span> <span class="kc">null</span><span 
class="o">;</span>
   <span class="o">}</span>
-
-  <span class="kd">final</span> <span class="n">UriResourceFunction</span> 
<span class="n">uriResourceFunction</span> <span class="o">=</span> <span 
class="o">(</span><span class="n">UriResourceFunction</span><span 
class="o">)</span> <span class="n">firstSegment</span><span class="o">;</span>
-  <span class="kd">final</span> <span class="n">EntityCollection</span> <span 
class="n">entityCol</span> <span class="o">=</span> <span 
class="n">storage</span><span class="o">.</span><span 
class="na">readFunctionImportCollection</span><span class="o">(</span><span 
class="n">uriResourceFunction</span><span class="o">,</span> <span 
class="n">serviceMetadata</span><span class="o">);</span>
 </pre></div>
 
 
-<p>Then the result has to be serialized. The only difference to entity sets is 
the way how the <code>EdmEntityType</code> is determined.</p>
-<div class="codehilite"><pre>  <span class="c1">// 2nd step: Serialize the 
response entity</span>
-  <span class="kd">final</span> <span class="n">EdmEntityType</span> <span 
class="n">edmEntityType</span> <span class="o">=</span> <span 
class="o">(</span><span class="n">EdmEntityType</span><span class="o">)</span> 
<span class="n">uriResourceFunction</span><span class="o">.</span><span 
class="na">getFunction</span><span class="o">().</span><span 
class="na">getReturnType</span><span class="o">().</span><span 
class="na">getType</span><span class="o">();</span>
-  <span class="kd">final</span> <span class="n">ContextURL</span> <span 
class="n">contextURL</span> <span class="o">=</span> <span 
class="n">ContextURL</span><span class="o">.</span><span 
class="na">with</span><span class="o">().</span><span 
class="na">asCollection</span><span class="o">().</span><span 
class="na">type</span><span class="o">(</span><span 
class="n">edmEntityType</span><span class="o">).</span><span 
class="na">build</span><span class="o">();</span>
-  <span class="n">EntityCollectionSerializerOptions</span> <span 
class="n">opts</span> <span class="o">=</span> <span 
class="n">EntityCollectionSerializerOptions</span><span class="o">.</span><span 
class="na">with</span><span class="o">().</span><span 
class="na">contextURL</span><span class="o">(</span><span 
class="n">contextURL</span><span class="o">).</span><span 
class="na">build</span><span class="o">();</span>
-  <span class="kd">final</span> <span class="n">ODataSerializer</span> <span 
class="n">serializer</span> <span class="o">=</span> <span 
class="n">odata</span><span class="o">.</span><span 
class="na">createSerializer</span><span class="o">(</span><span 
class="n">responseFormat</span><span class="o">);</span>
-  <span class="kd">final</span> <span class="n">SerializerResult</span> <span 
class="n">serializerResult</span> <span class="o">=</span> <span 
class="n">serializer</span><span class="o">.</span><span 
class="na">entityCollection</span><span class="o">(</span><span 
class="n">serviceMetadata</span><span class="o">,</span> <span 
class="n">edmEntityType</span><span class="o">,</span> <span 
class="n">entityCol</span><span class="o">,</span> <span 
class="n">opts</span><span class="o">);</span>
-
-  <span class="c1">// 3rd configure the response object</span>
-  <span class="n">response</span><span class="o">.</span><span 
class="na">setContent</span><span class="o">(</span><span 
class="n">serializerResult</span><span class="o">.</span><span 
class="na">getContent</span><span class="o">());</span>
-  <span class="n">response</span><span class="o">.</span><span 
class="na">setStatusCode</span><span class="o">(</span><span 
class="n">HttpStatusCode</span><span class="o">.</span><span 
class="na">OK</span><span class="o">.</span><span 
class="na">getStatusCode</span><span class="o">());</span>
-  <span class="n">response</span><span class="o">.</span><span 
class="na">setHeader</span><span class="o">(</span><span 
class="n">HttpHeader</span><span class="o">.</span><span 
class="na">CONTENT_TYPE</span><span class="o">,</span> <span 
class="n">responseFormat</span><span class="o">.</span><span 
class="na">toContentTypeString</span><span class="o">());</span>
-<span class="o">}</span>
-</pre></div>
+<p>In the second method, we are returning a custom object 
DemoEntityActionResult. This holds the entity and the status as to whether the 
entity is created or just returned. This information is used to set the 
response status</p>
+<div class="codehilite"><pre>    <span class="p">::::</span><span 
class="n">java</span>
 
+<span class="n">public</span> <span class="n">class</span> <span 
class="n">DemoEntityActionResult</span> <span class="p">{</span>
+  <span class="n">private</span> <span class="n">Entity</span> <span 
class="n">entity</span><span class="p">;</span>
+  <span class="n">private</span> <span class="n">boolean</span> <span 
class="n">created</span> <span class="p">=</span> <span 
class="n">false</span><span class="p">;</span>
 
-<p>Next we will implement the processor to read a <em>single entity</em>. The 
implementation is quite similar to the implementation of the collection 
processor.</p>
-<div class="codehilite"><pre><span class="kd">public</span> <span 
class="kt">void</span> <span class="nf">readEntity</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="n">public</span> <span class="n">Entity</span> <span 
class="n">getEntity</span><span class="p">()</span> <span class="p">{</span>
+    <span class="k">return</span> <span class="n">entity</span><span 
class="p">;</span>
+  <span class="p">}</span>
 
-  <span class="c1">// The sample service supports only functions imports and 
entity sets.</span>
-  <span class="c1">// We do not care about bound functions and composable 
functions.</span>
+  <span class="n">public</span> <span class="n">DemoEntityActionResult</span> 
<span class="n">setEntity</span><span class="p">(</span><span 
class="n">final</span> <span class="n">Entity</span> <span 
class="n">entity</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">this</span><span class="p">.</span><span 
class="n">entity</span> <span class="p">=</span> <span 
class="n">entity</span><span class="p">;</span>
+    <span class="k">return</span> <span class="n">this</span><span 
class="p">;</span>
+  <span class="p">}</span>
 
-  <span class="n">UriResource</span> <span class="n">uriResource</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="na">get</span><span class="o">(</span><span class="mi">0</span><span 
class="o">);</span>
+  <span class="n">public</span> <span class="n">boolean</span> <span 
class="n">isCreated</span><span class="p">()</span> <span class="p">{</span>
+    <span class="k">return</span> <span class="n">created</span><span 
class="p">;</span>
+  <span class="p">}</span>
 
-  <span class="k">if</span><span class="o">(</span><span 
class="n">uriResource</span> <span class="k">instanceof</span> <span 
class="n">UriResourceEntitySet</span><span class="o">)</span> <span 
class="o">{</span>
-    <span class="n">readEntityInternal</span><span class="o">(</span><span 
class="n">request</span><span class="o">,</span> <span 
class="n">response</span><span class="o">,</span> <span 
class="n">uriInfo</span><span class="o">,</span> <span 
class="n">responseFormat</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">uriResource</span> 
<span class="k">instanceof</span> <span 
class="n">UriResourceFunction</span><span class="o">)</span> <span 
class="o">{</span>
-    <span class="n">readFunctionImportInternal</span><span 
class="o">(</span><span class="n">request</span><span class="o">,</span> <span 
class="n">response</span><span class="o">,</span> <span 
class="n">uriInfo</span><span class="o">,</span> <span 
class="n">responseFormat</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">&quot;Only EntitySet is supported&quot;</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>
-
-<span class="kd">private</span> <span class="kt">void</span> <span 
class="nf">readFunctionImportInternal</span><span class="o">(</span><span 
class="kd">final</span> <span class="n">ODataRequest</span> <span 
class="n">request</span><span class="o">,</span> <span class="kd">final</span> 
<span class="n">ODataResponse</span> <span class="n">response</span><span 
class="o">,</span>
-  <span class="kd">final</span> <span class="n">UriInfo</span> <span 
class="n">uriInfo</span><span class="o">,</span> <span class="kd">final</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 step: Analyze the URI and fetch the entity returned 
by the function import</span>
-  <span class="c1">// Function Imports are always the first segment of the 
resource path</span>
-  <span class="kd">final</span> <span class="n">UriResource</span> <span 
class="n">firstSegment</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="na">get</span><span class="o">(</span><span class="mi">0</span><span 
class="o">);</span>
-
-  <span class="k">if</span><span class="o">(!(</span><span 
class="n">firstSegment</span> <span class="k">instanceof</span> <span 
class="n">UriResourceFunction</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">&quot;Not implemented&quot;</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="kd">final</span> <span class="n">UriResourceFunction</span> 
<span class="n">uriResourceFunction</span> <span class="o">=</span> <span 
class="o">(</span><span class="n">UriResourceFunction</span><span 
class="o">)</span> <span class="n">firstSegment</span><span class="o">;</span>
-  <span class="kd">final</span> <span class="n">Entity</span> <span 
class="n">entity</span> <span class="o">=</span> <span 
class="n">storage</span><span class="o">.</span><span 
class="na">readFunctionImportEntity</span><span class="o">(</span><span 
class="n">uriResourceFunction</span><span class="o">,</span> <span 
class="n">serviceMetadata</span><span class="o">);</span>
-
-  <span class="k">if</span><span class="o">(</span><span 
class="n">entity</span> <span class="o">==</span> <span 
class="kc">null</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">&quot;Nothing found.&quot;</span><span class="o">,</span>
-      <span class="n">HttpStatusCode</span><span class="o">.</span><span 
class="na">NOT_FOUND</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">ROOT</span><span class="o">);</span>
-  <span class="o">}</span>
+  <span class="n">public</span> <span class="n">DemoEntityActionResult</span> 
<span class="n">setCreated</span><span class="p">(</span><span 
class="n">final</span> <span class="n">boolean</span> <span 
class="n">created</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">this</span><span class="p">.</span><span 
class="n">created</span> <span class="p">=</span> <span 
class="n">created</span><span class="p">;</span>
+    <span class="k">return</span> <span class="n">this</span><span 
class="p">;</span>
+  <span class="p">}</span>
 
-  <span class="c1">// 2nd step: Serialize the response entity</span>
-  <span class="kd">final</span> <span class="n">EdmEntityType</span> <span 
class="n">edmEntityType</span> <span class="o">=</span> <span 
class="o">(</span><span class="n">EdmEntityType</span><span class="o">)</span> 
<span class="n">uriResourceFunction</span><span class="o">.</span><span 
class="na">getFunction</span><span class="o">().</span><span 
class="na">getReturnType</span><span class="o">().</span><span 
class="na">getType</span><span class="o">();</span>
-  <span class="kd">final</span> <span class="n">ContextURL</span> <span 
class="n">contextURL</span> <span class="o">=</span> <span 
class="n">ContextURL</span><span class="o">.</span><span 
class="na">with</span><span class="o">().</span><span 
class="na">type</span><span class="o">(</span><span 
class="n">edmEntityType</span><span class="o">).</span><span 
class="na">build</span><span class="o">();</span>
-  <span class="kd">final</span> <span class="n">EntitySerializerOptions</span> 
<span class="n">opts</span> <span class="o">=</span> <span 
class="n">EntitySerializerOptions</span><span class="o">.</span><span 
class="na">with</span><span class="o">().</span><span 
class="na">contextURL</span><span class="o">(</span><span 
class="n">contextURL</span><span class="o">).</span><span 
class="na">build</span><span class="o">();</span>
-  <span class="kd">final</span> <span class="n">ODataSerializer</span> <span 
class="n">serializer</span> <span class="o">=</span> <span 
class="n">odata</span><span class="o">.</span><span 
class="na">createSerializer</span><span class="o">(</span><span 
class="n">responseFormat</span><span class="o">);</span>
-  <span class="kd">final</span> <span class="n">SerializerResult</span> <span 
class="n">serializerResult</span> <span class="o">=</span> <span 
class="n">serializer</span><span class="o">.</span><span 
class="na">entity</span><span class="o">(</span><span 
class="n">serviceMetadata</span><span class="o">,</span> <span 
class="n">edmEntityType</span><span class="o">,</span> <span 
class="n">entity</span><span class="o">,</span> <span 
class="n">opts</span><span class="o">);</span>
-
-  <span class="c1">// 3rd configure the response object</span>
-  <span class="n">response</span><span class="o">.</span><span 
class="na">setContent</span><span class="o">(</span><span 
class="n">serializerResult</span><span class="o">.</span><span 
class="na">getContent</span><span class="o">());</span>
-  <span class="n">response</span><span class="o">.</span><span 
class="na">setStatusCode</span><span class="o">(</span><span 
class="n">HttpStatusCode</span><span class="o">.</span><span 
class="na">OK</span><span class="o">.</span><span 
class="na">getStatusCode</span><span class="o">());</span>
-  <span class="n">response</span><span class="o">.</span><span 
class="na">setHeader</span><span class="o">(</span><span 
class="n">HttpHeader</span><span class="o">.</span><span 
class="na">CONTENT_TYPE</span><span class="o">,</span> <span 
class="n">responseFormat</span><span class="o">.</span><span 
class="na">toContentTypeString</span><span class="o">());</span>
-<span class="o">}</span>
+<span class="p">}</span>
 </pre></div>
 
 
 <h3 id="implement-an-action-processor">Implement an action processor<a 
class="headerlink" href="#implement-an-action-processor" title="Permanent 
link">&para;</a></h3>
-<p>Create a new class <code>DemoActionProcessor</code> make them implement the 
interface <code>ActionVoidProcessor</code>.</p>

[... 239 lines stripped ...]

Reply via email to