olingo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r960770 - in /websites/staging/olingo/trunk/content: ./ doc/odata4/tutorials/navigation/tutorial_navigation.html
Date Tue, 04 Aug 2015 14:58:23 GMT
Author: buildbot
Date: Tue Aug  4 14:58:23 2015
New Revision: 960770

Log:
Staging update by buildbot for olingo

Modified:
    websites/staging/olingo/trunk/content/   (props changed)
    websites/staging/olingo/trunk/content/doc/odata4/tutorials/navigation/tutorial_navigation.html

Propchange: websites/staging/olingo/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Tue Aug  4 14:58:23 2015
@@ -1 +1 @@
-1694044
+1694074

Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/navigation/tutorial_navigation.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/navigation/tutorial_navigation.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/navigation/tutorial_navigation.html Tue Aug  4 14:58:23 2015
@@ -100,9 +100,14 @@ h2:hover > .headerlink, h3:hover > .head
 <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-4-navigation">Part 4: Navigation<a class="headerlink" href="#part-4-navigation" title="Permanent link">&para;</a></h1>
 <h2 id="introduction">Introduction<a class="headerlink" href="#introduction" title="Permanent link">&para;</a></h2>
-<p>In the present tutorial, we’ll learn how to implement navigation between 2 Entity Types in an OData V4 service.</p>
-<p><strong>Background</strong>
-Say, we have an electronics shop and we have a lot of products which we’re selling and these products can be notebooks or monitors or organizers, which are the categories.
+<p>In the present tutorial, we will learn how to implement navigation between 2 Entity Types in an OData V4 service.</p>
+<p><strong>Note</strong>  </p>
+<p>The full implementation of the OData service as described in the present tutorial can be found in the <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip">attached zip file</a> (<a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip.md5">md5</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip.sha512">sha512</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip.asc">pgp</a>) that contains an Eclipse project that can be imported into your Eclipse workspace.</p>
+<p><strong>Disclaimer</strong>  </p>
+<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 shouldn’t be reused for advanced scenarios.</p>
+<p><strong>Background</strong>  </p>
+<p>Say, we have an electronics shop and we have a lot of products which we’re selling and these products can be notebooks or monitors or organizers, which are the categories.
 We would have 3 requirements:</p>
 <ol>
 <li>We want to show a list of all our categories, then select one and display a list of all products that belong to this category, e.g. all monitors
@@ -110,26 +115,21 @@ We would have 3 requirements:</p>
 <li>From the list of our products, we want to choose one and display its category</li>
 <li>We want to navigate from a category to its products and perform a READ operation on one of them.</li>
 </ol>
-<p><strong>Example for navigating in a service</strong>
-We open the Categories collection: <a href="http://localhost:8080/DemoService/DemoService.svc/Categories">http://localhost:8080/DemoService/DemoService.svc/Categories</a></p>
+<p><strong>Example for navigating in a service</strong></p>
+<p>We open the Categories collection: <a href="http://localhost:8080/DemoService/DemoService.svc/Categories">http://localhost:8080/DemoService/DemoService.svc/Categories</a></p>
 <p><img alt="CategoryCollection" src="browser_categories.JPG" title="The Category collection" /></p>
 <p>We open the details of the first Category, the “Notebooks”-category:
-http://localhost:8080/DemoService/DemoService.svc/Categories(1)</p>
+<a href="http://localhost:8080/DemoService/DemoService.svc/Categories(1)">http://localhost:8080/DemoService/DemoService.svc/Categories(1)</a></p>
 <p><img alt="CategoryEntity" src="browser_categories1.jpg" title="Read single Category entity" /></p>
 <p>In order to display all products that are notebooks, we can navigate from the selected category to its products:
-http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products</p>
+<a href="http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products">http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products</a></p>
 <p><img alt="ProductsOfCategory" src="browser_categories1_products.jpg" title="After navigating from a Category to the related Products" /></p>
 <p>In the above example we’ve executed a one-to-many navigation.</p>
 <p>As mentioned in the Background section, it is also required to navigate from a selected product to its category, which is a to-one relation, like:
-http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category</p>
+<a href="http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category">http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category</a></p>
 <p>And finally, it is possible to navigate to a list of products and directly access one of them, e.g.
-http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products(1)</p>
+<a href="http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products(1)">http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products(1)</a></p>
 <p>All three cases are covered by the present tutorial.</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 shouldn’t be reused for advanced scenarios.</p>
 <p><strong>Table of Contents</strong></p>
 <ol>
 <li>Prerequisites</li>
@@ -148,11 +148,10 @@ The sample code shouldn’t be reused
 </ol>
 <hr />
 <h1 id="1-prerequisites">1. Prerequisites<a class="headerlink" href="#1-prerequisites" title="Permanent link">&para;</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>
- and <a href="http://olingo.apache.org/doc/odata4/tutorials/readep/tutorial_readep.html">Tutorial Part 2: Read Entity</a> as well as basic knowledge about the concepts presented in both tutorials.</p>
+<p>Same prerequisites as in <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> as well as basic knowledge about the concepts presented in both tutorials.</p>
 <hr />
 <h1 id="2-preparation">2. Preparation<a class="headerlink" href="#2-preparation" title="Permanent link">&para;</a></h1>
-<p>Follow Tutorial Part 1: Read Entity Collection and Tutorial Part 2: Read Entity 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">project attached to Tutorial Part 2</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>) into your Eclipse workspace (.</p>
 <p>Afterwards do a Deploy and run: it should be working.</p>
 <hr />
 <h1 id="3-implementing-the-navigation">3. Implementing the navigation<a class="headerlink" href="#3-implementing-the-navigation" title="Permanent link">&para;</a></h1>
@@ -166,7 +165,7 @@ E.g. a product with name “Brilliant
 But this is not necessary, because that information can be obtained by navigating to the respective “Category”-entity using the navigation property.
 That way, we can keep the entity types lightweight, which is one of the intentions of OData.</p>
 <h2 id="31-declare-the-metadata">3.1. Declare the metadata<a class="headerlink" href="#31-declare-the-metadata" title="Permanent link">&para;</a></h2>
-<p>In order to declare the metadata of our OData service, we open the class <em>myservice.mynamespace.service.DemoEdmProvider</em></p>
+<p>In order to declare the metadata of our OData service, we open the class myservice.mynamespace.service.DemoEdmProvider_</p>
 <h3 id="311-extend-the-entity-type-product">3.1.1. Extend the Entity Type “Product”<a class="headerlink" href="#311-extend-the-entity-type-product" title="Permanent link">&para;</a></h3>
 <p>In the previous tutorial we’ve already created the metadata for the “Product” entity type:</p>
 <div class="codehilite"><pre><span class="nt">&lt;EntityType</span> <span class="na">Name=</span><span class="s">&quot;Product&quot;</span><span class="nt">&gt;</span>
@@ -183,7 +182,7 @@ That way, we can keep the entity types l
 <p>Now we have to add a navigation property.
 That navigation property element has the following attributes:</p>
 <p><strong>Name</strong>
-Tthe name of the navigation property is used as segment in the URI
+The name of the navigation property is used as segment in the URI
 e.g. for the following URL: <a href="http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category">http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category</a>
 The segment “Category” is the name of the navigation property</p>
 <p><strong>Type</strong>
@@ -214,7 +213,7 @@ In our example, we can navigate from pro
 </pre></div>
 
 
-<p>Implementation-wise we have to create and configure an object of type <em>CsdlNavigationProperty</em>:</p>
+<p>Implementation-wise we have to create and configure an object of type <code>CsdlNavigationProperty</code>:</p>
 <div class="codehilite"><pre><span class="n">CsdlNavigationProperty</span> <span class="n">navProp</span> <span class="o">=</span> <span class="k">new</span> <span class="n">CsdlNavigationProperty</span><span class="o">()</span>
                                     <span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">&quot;Category&quot;</span><span class="o">)</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>
@@ -236,14 +235,14 @@ In our example, we can navigate from pro
 
 <p>There’s one more step to consider with respect to the navigation: the entity set.
 At runtime, we need to know how to implement the navigation, when an entity set is invoked.
-For this purpose, the OData specifies the <em>NavigationPropertyBinding</em> element, which is a child element of the entity set and should be defined for each navigation property.
-That <em>NavigationPropertyBinding</em> has the following attributes:</p>
+For this purpose, the OData specifies the <code>NavigationPropertyBinding</code> element, which is a child element of the entity set and should be defined for each navigation property.
+That <code>NavigationPropertyBinding</code> has the following attributes:</p>
 <p><strong>Path</strong>
 Here we specify the name of the corresponding navigation property.
 In our example, the navigation property that we’ve defined above is named “Category”</p>
 <p><strong>Target</strong>
 Here we specify the entity set where we’re navigating to.
-In our example it is the entity set “Categories” (which we’ll create below)</p>
+In our example it is the entity set “Categories” (which we will create below)</p>
 <p>In our example, the definition of our “Products” entity set looks as follows:</p>
 <div class="codehilite"><pre><span class="nt">&lt;EntitySet</span> <span class="na">Name=</span><span class="s">&quot;Products&quot;</span> <span class="na">EntityType=</span><span class="s">&quot;OData.Demo.Product&quot;</span><span class="nt">&gt;</span>
   <span class="nt">&lt;NavigationPropertyBinding</span> <span class="na">Path=</span><span class="s">&quot;Category&quot;</span> <span class="na">Target=</span><span class="s">&quot;Categories&quot;</span><span class="nt">/&gt;</span>
@@ -321,7 +320,7 @@ In our example, we’re defining a bi
 </pre></div>
 
 
-<p>The <em>NavigationPropertyBinding</em> element and its attributes for the entity set “Categories”:</p>
+<p>The <code>NavigationPropertyBinding</code> element and its attributes for the entity set “Categories”:</p>
 <p><strong>Path</strong>
 In our example, the navigation property that we’ve defined above is named “Products”</p>
 <p><strong>Target</strong>
@@ -333,7 +332,7 @@ In our example it is the entity set â€
 </pre></div>
 
 
-<p>And the implementation in the <em>getEntitySet</em> method:</p>
+<p>And the implementation in the <code>getEntitySet</code> method:</p>
 <div class="codehilite"><pre><span class="n">CsdlNavigationPropertyBinding</span> <span class="n">navPropBinding</span> <span class="o">=</span> <span class="k">new</span> <span class="n">CsdlNavigationPropertyBinding</span><span class="o">();</span>
 <span class="n">navPropBinding</span><span class="o">.</span><span class="na">setTarget</span><span class="o">(</span><span class="s">&quot;Products&quot;</span><span class="o">);</span><span class="c1">//target entitySet, where the nav prop points to</span>
 <span class="n">navPropBinding</span><span class="o">.</span><span class="na">setPath</span><span class="o">(</span><span class="s">&quot;Products&quot;</span><span class="o">);</span> <span class="c1">// the path from entity type to navigation property</span>
@@ -353,7 +352,7 @@ So the user has to check the metadata do
 <p><img alt="CategoryMetadata" src="browser_metadataCategory.JPG" title="The definition of a Navigation Property in the $metadata document" /></p>
 <p>This means, that he can append the navigation property name to his URL, which takes him to the set of “Products” that belong to the chosen “Category”: <a href="http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products">http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products</a></p>
 <p>From the metadata we can see that the “Type” attribute defines a collection.
-This means that the implementation has to be done in the <em>EntityCollectionProcessor</em>, since we have to provide a collection of entities.</p>
+This means that the implementation has to be done in the <code>EntityCollectionProcessor</code>, since we have to provide a collection of entities.</p>
 <p>Open the class <code>myservice.mynamespace.service.DemoEntityCollectionProcessor.java</code></p>
 <p>There, the implementation for a “normal” read operation is already in place and we have to add the case when an entity collection is expected after navigation.
 Note that we want to keep our tutorial and our code simple, so we decide that only one step navigation is to be supported by our service.
@@ -363,7 +362,7 @@ Categories(1)/Products
 We don’t support navigation from one entity to an entity and then to another entity and so on
 For example:
 Categories(1)/Products(1)/Category</p>
-<p>Based on this assumption, in our <em>EntityCollectionProcessor</em>, we can rely on the fact that the URI can have either one or two segments.
+<p>Based on this assumption, in our <code>EntityCollectionProcessor</code>, we can rely on the fact that the URI can have either one or two segments.
 This means: we can be called for the following kind of URLs:</p>
 <p>Example URL for one sement: <a href="http://localhost:8080/DemoService/DemoService.svc/Categories">http://localhost:8080/DemoService/DemoService.svc/Categories</a></p>
 <p>Example URL for two segments: <a href="http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products">http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products</a></p>
@@ -401,7 +400,7 @@ For the first case, we have only one ent
   1. depending on the chosen key of the first segment, we have to compute which and how many entities exactly have to be returned. With other words, find the right data in the backend
   e.g. for the category “monitors”, we have to find the right products that are monitors
   2. find out, which entity set has to be returned (can be products, categories, etc)
-  This <em>EdmEntitySet</em> is required in order to properly build the context URL</p>
+  This <code>EdmEntitySet</code> is required in order to properly build the context URL</p>
 <p>The following sections explain how to do that.</p>
 <h3 id="321-get-the-data-for-the-response">3.2.1. Get the data for the response<a class="headerlink" href="#321-get-the-data-for-the-response" title="Permanent link">&para;</a></h3>
 <p>Getting the data for the response is reylized in 2 steps:</p>
@@ -409,14 +408,14 @@ For the first case, we have only one ent
 in our example, we have to perform a read operation for retrieving the Category with ID 3, which is "Monitors"</p>
 <p><strong>B)</strong> get the data for the navigation
 in our example, we have to find the products that are monitors.</p>
-<p>With respect to data, remember that we're using sample data that we create in our Storage class which represents our kind of database-mock.
+<p>With respect to data, remember that we're using sample data that we create in our <code>Storage</code> class which represents our kind of database-mock.<br />
 On startup of our service, we initialize some sample products and categories.
 During initialization, there’s no assignment of products to its categories.
-In our sample code, we’re doing this when requested in a hard-coded method in our <em>Storage</em> class.</p>
+In our sample code, we’re doing this when requested in a hard-coded method in our <code>Storage</code> class.</p>
 <p><strong>A) get the data for the first URI segment</strong></p>
-<p>In our example, the URL would be: <a href="http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products">http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products</a>
-For this example, we would have to retrieve the Category with ID=3
-The code looks like a normal READ operation:</p>
+<p>In our example, the URL would be: <a href="http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products">http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products</a></p>
+<p>For this example, we would have to retrieve the Category with <em>ID=3</em>.<br />
+The code looks like a normal <code>READ</code> operation:</p>
 <div class="codehilite"><pre><span class="n">List</span><span class="o">&lt;</span><span class="n">UriParameter</span><span class="o">&gt;</span> <span class="n">keyPredicates</span> <span class="o">=</span> <span class="n">uriResourceEntitySet</span><span class="o">.</span><span class="na">getKeyPredicates</span><span class="o">();</span>
 <span class="n">Entity</span> <span class="n">sourceEntity</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="na">readEntityData</span><span class="o">(</span><span class="n">startEdmEntitySet</span><span class="o">,</span> <span class="n">keyPredicates</span><span class="o">);</span>
 </pre></div>
@@ -424,7 +423,7 @@ The code looks like a normal READ operat
 
 <p>In our example, the result is an entity that represents the “Monitors” – category.</p>
 <p><strong>B) get the data for the navigation</strong></p>
-<p>Now we have to follow the navigation, based on the retrieved entity.
+<p>Now we have to follow the navigation, based on the retrieved entity.<br />
 In our example, we have to retrieve all products that are monitors.</p>
 <p>This is backend logic, so we can directly call a helper method in our Storage class:</p>
 <div class="codehilite"><pre><span class="n">responseEntityCollection</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="na">getRelatedEntityCollection</span><span class="o">(</span><span class="n">sourceEntity</span><span class="o">,</span> <span class="n">targetEntityType</span><span class="o">);</span>
@@ -432,17 +431,17 @@ In our example, we have to retrieve all
 
 
 <p>This helper method requires the source entity and returns the target collection.
-Additionally, the method needs the <em>EdmEntityType</em> that corresponds to the requested target.
+Additionally, the method needs the <code>EdmEntityType</code> that corresponds to the requested target.
 In our example, we pass the “Category” (i.e. "Monitors") as source entity and the navigation target entity type, which is “Product”.
 As a result, we get the desired “Products” collection, all products that are monitors.</p>
 <p>After this step, we’re almost done, because we have the entity collection that our OData service returns in the response body.
 We only need to do some more hand work: the response entity collection has to be serialized and the serializer which is in charge of doing that has to be configured properly.
-For that we need the <em>EdmEntitySet</em> that corresponds to the response.
+For that we need the <code>EdmEntitySet</code> that corresponds to the response.
 Since it is different in case of navigation and non-navigation, we still need to retrieve it for the case of navigation.</p>
 <h3 id="322-retrieve-the-edmentityset-for-the-response">3.2.2. Retrieve the EdmEntitySet for the response<a class="headerlink" href="#322-retrieve-the-edmentityset-for-the-response" title="Permanent link">&para;</a></h3>
 <p>First, we have to analyze the URI, and find out if the URI segment is used for navigation.
 As mentioned, in our simple example we assume that the second segment is used for navigation (in advanced services, a segment could as well be an action or function import, etc).
-The navigation URI segment can then be asked for the corresponding <em>EdmNavigationProperty</em></p>
+The navigation URI segment can then be asked for the corresponding <code>EdmNavigationProperty</code></p>
 <div class="codehilite"><pre><span class="n">UriResource</span> <span class="n">lastSegment</span> <span class="o">=</span> <span class="n">resourceParts</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="mi">1</span><span class="o">);</span>
 <span class="k">if</span><span class="o">(</span><span class="n">lastSegment</span> <span class="k">instanceof</span> <span class="n">UriResourceNavigation</span><span class="o">){</span>
     <span class="n">UriResourceNavigation</span> <span class="n">uriResourceNavigation</span> <span class="o">=</span> <span class="o">(</span><span class="n">UriResourceNavigation</span><span class="o">)</span><span class="n">lastSegment</span><span class="o">;</span>
@@ -450,7 +449,7 @@ The navigation URI segment can then be a
 </pre></div>
 
 
-<p>The bad news is that the <em>EdmNavigationProperty</em> doesn’t know about the target <em>EdmEntitySet</em>.
+<p>The bad news is that the <code>EdmNavigationProperty</code> doesn’t know about the target <code>EdmEntitySet</code>.
 This is as per design, just check the metadata:</p>
 <div class="codehilite"><pre><span class="nt">&lt;EntityType</span> <span class="na">Name=</span><span class="s">&quot;Category&quot;</span><span class="nt">&gt;</span>
     ...
@@ -469,11 +468,11 @@ The target entity set is defined in the
 
 <p>This is where we get the information that we need.</p>
 <p>For our implementation, this means:
-  1. we need the <em>EdmEntiySet</em> that corresponds to the first segment of the URI
+  1. we need the <code>EdmEntitySet</code> that corresponds to the first segment of the URI
     in our example: Categories
   2. we need the navigation property that corresponds to the second segment of the URI
     in our example: Products</p>
-<p>As shown below, from the source <em>EdmEntitySet</em> we get the binding target, based on the navigation property.</p>
+<p>As shown below, from the source <code>EdmEntitySet</code> we get the binding target, based on the navigation property.</p>
 <div class="codehilite"><pre><span class="n">EdmBindingTarget</span> <span class="n">edmBindingTarget</span> <span class="o">=</span> <span class="n">startEntitySet</span><span class="o">.</span><span class="na">getRelatedBindingTarget</span><span class="o">(</span><span class="n">navPropName</span><span class="o">);</span>
 <span class="k">if</span><span class="o">(</span><span class="n">edmBindingTarget</span> <span class="k">instanceof</span> <span class="n">EdmEntitySet</span><span class="o">){</span>
     <span class="n">navigationTargetEntitySet</span> <span class="o">=</span> <span class="o">(</span><span class="n">EdmEntitySet</span><span class="o">)</span><span class="n">edmBindingTarget</span><span class="o">;</span>
@@ -481,74 +480,71 @@ The target entity set is defined in the
 
 
 <p>This target is the entity set that we need.</p>
-<p>We move the code into the utility method <em>Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty)</em>
+<p>We move the code into the utility method <code>Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty)</code>
 Reason is that we'll need it again, later in this tutorial.</p>
 <h3 id="323-remaining-tasks">3.2.3 Remaining tasks<a class="headerlink" href="#323-remaining-tasks" title="Permanent link">&para;</a></h3>
-<p>In the previous tutorials we’ve already learned what else has to be done: transform the retrieve data into an <em>InputStream</em> i.e. serialize the content.
+<p>In the previous tutorials we’ve already learned what else has to be done: transform the retrieve data into an <code>InputStream</code> i.e. serialize the content.
 Furthermore, configure the response object, i.e. set the response body, the content type and the header.</p>
-<p>The following snippet shows the implementation of the <em>readEntityCollection(…)</em> method.</p>
-<div class="codehilite"><pre>
-</pre></div>
+<p>The following snippet shows the implementation of the <code>readEntityCollection(…)</code> 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>
+                                <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">EdmEntitySet</span> <span class="n">responseEdmEntitySet</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> <span class="c1">// for building ContextURL</span>
+<span class="n">EntityCollection</span> <span class="n">responseEntityCollection</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> <span class="c1">// for the response body</span>
+
+<span class="c1">// 1st retrieve the requested EntitySet from the uriInfo</span>
+<span class="n">List</span><span class="o">&lt;</span><span class="n">UriResource</span><span class="o">&gt;</span> <span class="n">resourceParts</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="kt">int</span> <span class="n">segmentCount</span> <span class="o">=</span> <span class="n">resourceParts</span><span class="o">.</span><span class="na">size</span><span class="o">();</span>
+
+<span class="n">UriResource</span> <span class="n">uriResource</span> <span class="o">=</span> <span class="n">resourceParts</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">// the first segment is the EntitySet</span>
+<span class="k">if</span> <span class="o">(!</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="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">ROOT</span><span class="o">);</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">uriResource</span><span class="o">;</span>
+<span class="n">EdmEntitySet</span> <span class="n">startEdmEntitySet</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="k">if</span><span class="o">(</span><span class="n">segmentCount</span> <span class="o">==</span> <span class="mi">1</span><span class="o">){</span> <span class="c1">// this is the case for: DemoService/DemoService.svc/Categories</span>
+    <span class="n">responseEdmEntitySet</span> <span class="o">=</span> <span class="n">startEdmEntitySet</span><span class="o">;</span> <span class="c1">// first (and only) entitySet</span>
 
-<p>public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
-                                    throws ODataApplicationException, SerializerException {</p>
-<div class="codehilite"><pre><span class="n">EdmEntitySet</span> <span class="n">responseEdmEntitySet</span> <span class="p">=</span> <span class="n">null</span><span class="p">;</span> <span class="o">//</span> <span class="k">for</span> <span class="n">building</span> <span class="n">ContextURL</span>
-<span class="n">EntityCollection</span> <span class="n">responseEntityCollection</span> <span class="p">=</span> <span class="n">null</span><span class="p">;</span> <span class="o">//</span> <span class="k">for</span> <span class="n">the</span> <span class="n">response</span> <span class="n">body</span>
-
-<span class="o">//</span> 1<span class="n">st</span> <span class="n">retrieve</span> <span class="n">the</span> <span class="n">requested</span> <span class="n">EntitySet</span> <span class="n">from</span> <span class="n">the</span> <span class="n">uriInfo</span>
-<span class="n">List</span><span class="o">&lt;</span><span class="n">UriResource</span><span class="o">&gt;</span> <span class="n">resourceParts</span> <span class="p">=</span> <span class="n">uriInfo</span><span class="p">.</span><span class="n">getUriResourceParts</span><span class="p">();</span>
-<span class="n">int</span> <span class="n">segmentCount</span> <span class="p">=</span> <span class="n">resourceParts</span><span class="p">.</span><span class="nb">size</span><span class="p">();</span>
-
-<span class="n">UriResource</span> <span class="n">uriResource</span> <span class="p">=</span> <span class="n">resourceParts</span><span class="p">.</span><span class="n">get</span><span class="p">(</span>0<span class="p">);</span> <span class="o">//</span> <span class="n">the</span> <span class="n">first</span> <span class="n">segment</span> <span class="n">is</span> <span class="n">the</span> <span class="n">EntitySet</span>
-<span class="k">if</span> <span class="p">(</span>! <span class="p">(</span><span class="n">uriResource</span> <span class="n">instanceof</span> <span class="n">UriResourceEntitySet</span><span class="p">))</span> <span class="p">{</span>
-    <span class="n">throw</span> <span class="n">new</span> <span class="n">ODataApplicationException</span><span class="p">(</span>&quot;<span class="n">Only</span> <span class="n">EntitySet</span> <span class="n">is</span> <span class="n">supported</span>&quot;<span class="p">,</span> <span class="n">HttpStatusCode</span><span class="p">.</span><span class="n">NOT_IMPLEMENTED</span><span class="p">.</span><span class="n">getStatusCode</span><span class="p">(),</span><span class="n">Locale</span><span class="p">.</span><span class="n">ROOT</span><span class="p">);</span>
-<span class="p">}</span>
-
-<span class="n">UriResourceEntitySet</span> <span class="n">uriResourceEntitySet</span> <span class="p">=</span> <span class="p">(</span><span class="n">UriResourceEntitySet</span><span class="p">)</span> <span class="n">uriResource</span><span class="p">;</span>
-<span class="n">EdmEntitySet</span> <span class="n">startEdmEntitySet</span> <span class="p">=</span> <span class="n">uriResourceEntitySet</span><span class="p">.</span><span class="n">getEntitySet</span><span class="p">();</span>
-
-<span class="k">if</span><span class="p">(</span><span class="n">segmentCount</span> <span class="o">==</span> 1<span class="p">){</span> <span class="o">//</span> <span class="n">this</span> <span class="n">is</span> <span class="n">the</span> <span class="k">case</span> <span class="k">for</span><span class="p">:</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">Categories</span>
-    <span class="n">responseEdmEntitySet</span> <span class="p">=</span> <span class="n">startEdmEntitySet</span><span class="p">;</span> <span class="o">//</span> <span class="n">first</span> <span class="p">(</span><span class="n">and</span> <span class="n">only</span><span class="p">)</span> <span class="n">entitySet</span>
-
-    <span class="o">//</span> 2<span class="n">nd</span><span class="p">:</span> <span class="n">fetch</span> <span class="n">the</span> <span class="n">data</span> <span class="n">from</span> <span class="n">backend</span> <span class="k">for</span> <span class="n">this</span> <span class="n">requested</span> <span class="n">EntitySetName</span>
-    <span class="n">responseEntityCollection</span> <span class="p">=</span> <span class="n">storage</span><span class="p">.</span><span class="n">readEntitySetData</span><span class="p">(</span><span class="n">startEdmEntitySet</span><span class="p">);</span>
-<span class="p">}</span><span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">segmentCount</span> <span class="o">==</span> 2<span class="p">){</span> <span class="o">//</span><span class="n">navigation</span><span class="p">:</span> <span class="n">e</span><span class="p">.</span><span class="n">g</span><span class="p">.</span> <span class="n">DemoService</span><span class="p">.</span><span class="n">svc</span><span class="o">/</span><span class="n">Categories</span><span class="p">(</span>3<span class="p">)</span><span class="o">/</span><span class="n">Products</span>
-    <span class="n">UriResource</span> <span class="n">lastSegment</span> <span class="p">=</span> <span class="n">resourceParts</span><span class="p">.</span><span class="n">get</span><span class="p">(</span>1<span class="p">);</span> <span class="o">//</span> <span class="n">don</span><span class="o">&#39;</span><span class="n">t</span> <span class="n">support</span> <span class="n">more</span> <span class="nb">complex</span> <span class="n">URIs</span>
-    <span class="k">if</span><span class="p">(</span><span class="n">lastSegment</span> <span class="n">instanceof</span> <span class="n">UriResourceNavigation</span><span class="p">){</span>
-        <span class="n">UriResourceNavigation</span> <span class="n">uriResourceNavigation</span> <span class="p">=</span> <span class="p">(</span><span class="n">UriResourceNavigation</span><span class="p">)</span><span class="n">lastSegment</span><span class="p">;</span>
-        <span class="n">EdmNavigationProperty</span> <span class="n">edmNavigationProperty</span> <span class="p">=</span> <span class="n">uriResourceNavigation</span><span class="p">.</span><span class="n">getProperty</span><span class="p">();</span>
-        <span class="n">EdmEntityType</span> <span class="n">targetEntityType</span> <span class="p">=</span> <span class="n">edmNavigationProperty</span><span class="p">.</span><span class="n">getType</span><span class="p">();</span>
-        <span class="n">responseEdmEntitySet</span> <span class="p">=</span> <span class="n">Util</span><span class="p">.</span><span class="n">getNavigationTargetEntitySet</span><span class="p">(</span><span class="n">startEdmEntitySet</span><span class="p">,</span> <span class="n">edmNavigationProperty</span><span class="p">);</span>
-
-        <span class="o">//</span> 2<span class="n">nd</span><span class="p">:</span> <span class="n">fetch</span> <span class="n">the</span> <span class="n">data</span> <span class="n">from</span> <span class="n">backend</span>
-        <span class="o">//</span> <span class="n">first</span> <span class="n">fetch</span> <span class="n">the</span> <span class="n">entity</span> <span class="n">where</span> <span class="n">the</span> <span class="n">first</span> <span class="n">segment</span> <span class="n">of</span> <span class="n">the</span> <span class="n">URI</span> <span class="n">points</span> <span class="n">to</span>
-        <span class="o">//</span> <span class="n">e</span><span class="p">.</span><span class="n">g</span><span class="p">.</span> <span class="n">Categories</span><span class="p">(</span>3<span class="p">)</span><span class="o">/</span><span class="n">Products</span> <span class="n">first</span> <span class="nb">find</span> <span class="n">the</span> <span class="n">single</span> <span class="n">entity</span><span class="p">:</span> <span class="n">Category</span><span class="p">(</span>3<span class="p">)</span>
-        <span class="n">List</span><span class="o">&lt;</span><span class="n">UriParameter</span><span class="o">&gt;</span> <span class="n">keyPredicates</span> <span class="p">=</span> <span class="n">uriResourceEntitySet</span><span class="p">.</span><span class="n">getKeyPredicates</span><span class="p">();</span>
-        <span class="n">Entity</span> <span class="n">sourceEntity</span> <span class="p">=</span> <span class="n">storage</span><span class="p">.</span><span class="n">readEntityData</span><span class="p">(</span><span class="n">startEdmEntitySet</span><span class="p">,</span> <span class="n">keyPredicates</span><span class="p">);</span>
-        <span class="o">//</span> <span class="n">error</span> <span class="n">handling</span> <span class="k">for</span> <span class="n">e</span><span class="p">.</span><span class="n">g</span><span class="p">.</span>  <span class="n">DemoService</span><span class="p">.</span><span class="n">svc</span><span class="o">/</span><span class="n">Categories</span><span class="p">(</span>99<span class="p">)</span><span class="o">/</span><span class="n">Products</span>
-        <span class="k">if</span><span class="p">(</span><span class="n">sourceEntity</span> <span class="o">==</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
-            <span class="n">throw</span> <span class="n">new</span> <span class="n">ODataApplicationException</span><span class="p">(</span>&quot;<span class="n">Entity</span> <span class="n">not</span> <span class="n">found</span><span class="p">.</span>&quot;<span class="p">,</span> <span class="n">HttpStatusCode</span><span class="p">.</span><span class="n">NOT_FOUND</span><span class="p">.</span><span class="n">getStatusCode</span><span class="p">(),</span> <span class="n">Locale</span><span class="p">.</span><span class="n">ROOT</span><span class="p">);</span>
-        <span class="p">}</span>
-        <span class="o">//</span> <span class="n">then</span> <span class="n">fetch</span> <span class="n">the</span> <span class="n">entity</span> <span class="n">collection</span> <span class="n">where</span> <span class="n">the</span> <span class="n">entity</span> <span class="n">navigates</span> <span class="n">to</span>
-        <span class="n">responseEntityCollection</span> <span class="p">=</span> <span class="n">storage</span><span class="p">.</span><span class="n">getRelatedEntityCollection</span><span class="p">(</span><span class="n">sourceEntity</span><span class="p">,</span> <span class="n">targetEntityType</span><span class="p">);</span>
-    <span class="p">}</span>
-<span class="p">}</span><span class="k">else</span><span class="p">{</span> <span class="o">//</span> <span class="n">this</span> <span class="n">would</span> <span class="n">be</span> <span class="n">the</span> <span class="k">case</span> <span class="k">for</span> <span class="n">e</span><span class="p">.</span><span class="n">g</span><span class="p">.</span> <span class="n">Products</span><span class="p">(</span>1<span class="p">)</span><span class="o">/</span><span class="n">Category</span><span class="o">/</span><span class="n">Products</span>
-    <span class="n">throw</span> <span class="n">new</span> <span class="n">ODataApplicationException</span><span class="p">(</span>&quot;<span class="n">Not</span> <span class="n">supported</span>&quot;<span class="p">,</span> <span class="n">HttpStatusCode</span><span class="p">.</span><span class="n">NOT_IMPLEMENTED</span><span class="p">.</span><span class="n">getStatusCode</span><span class="p">(),</span><span class="n">Locale</span><span class="p">.</span><span class="n">ROOT</span><span class="p">);</span>
-<span class="p">}</span>
-
-<span class="o">//</span> 3<span class="n">rd</span><span class="p">:</span> <span class="n">create</span> <span class="n">and</span> <span class="n">configure</span> <span class="n">a</span> <span class="n">serializer</span>
-<span class="n">ContextURL</span> <span class="n">contextUrl</span> <span class="p">=</span> <span class="n">ContextURL</span><span class="p">.</span><span class="n">with</span><span class="p">().</span><span class="n">entitySet</span><span class="p">(</span><span class="n">responseEdmEntitySet</span><span class="p">).</span><span class="n">build</span><span class="p">();</span>
-<span class="n">EntityCollectionSerializerOptions</span> <span class="n">opts</span> <span class="p">=</span> <span class="n">EntityCollectionSerializerOptions</span><span class="p">.</span><span class="n">with</span><span class="p">().</span><span class="n">contextURL</span><span class="p">(</span><span class="n">contextUrl</span><span class="p">).</span><span class="n">build</span><span class="p">();</span>
-<span class="n">EdmEntityType</span> <span class="n">edmEntityType</span> <span class="p">=</span> <span class="n">responseEdmEntitySet</span><span class="p">.</span><span class="n">getEntityType</span><span class="p">();</span>
-
-<span class="n">ODataSerializer</span> <span class="n">serializer</span> <span class="p">=</span> <span class="n">odata</span><span class="p">.</span><span class="n">createSerializer</span><span class="p">(</span><span class="n">ODataFormat</span><span class="p">.</span><span class="n">fromContentType</span><span class="p">(</span><span class="n">responseFormat</span><span class="p">));</span>
-<span class="n">SerializerResult</span> <span class="n">serializerResult</span> <span class="p">=</span> <span class="n">serializer</span><span class="p">.</span><span class="n">entityCollection</span><span class="p">(</span><span class="n">this</span><span class="p">.</span><span class="n">srvMetadata</span><span class="p">,</span> <span class="n">edmEntityType</span><span class="p">,</span> <span class="n">responseEntityCollection</span><span class="p">,</span> <span class="n">opts</span><span class="p">);</span>
-
-<span class="o">//</span> 4<span class="n">th</span><span class="p">:</span> <span class="n">configure</span> <span class="n">the</span> <span class="n">response</span> <span class="n">object</span><span class="p">:</span> <span class="n">set</span> <span class="n">the</span> <span class="n">body</span><span class="p">,</span> <span class="n">headers</span> <span class="n">and</span> <span class="n">status</span> <span class="n">code</span>
-<span class="n">response</span><span class="p">.</span><span class="n">setContent</span><span class="p">(</span><span class="n">serializerResult</span><span class="p">.</span><span class="n">getContent</span><span class="p">());</span>
-<span class="n">response</span><span class="p">.</span><span class="n">setStatusCode</span><span class="p">(</span><span class="n">HttpStatusCode</span><span class="p">.</span><span class="n">OK</span><span class="p">.</span><span class="n">getStatusCode</span><span class="p">());</span>
-<span class="n">response</span><span class="p">.</span><span class="n">setHeader</span><span class="p">(</span><span class="n">HttpHeader</span><span class="p">.</span><span class="n">CONTENT_TYPE</span><span class="p">,</span> <span class="n">responseFormat</span><span class="p">.</span><span class="n">toContentTypeString</span><span class="p">());</span>
+    <span class="c1">// 2nd: fetch the data from backend for this requested EntitySetName</span>
+    <span class="n">responseEntityCollection</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">startEdmEntitySet</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">segmentCount</span> <span class="o">==</span> <span class="mi">2</span><span class="o">){</span> <span class="c1">//navigation: e.g. DemoService.svc/Categories(3)/Products</span>
+    <span class="n">UriResource</span> <span class="n">lastSegment</span> <span class="o">=</span> <span class="n">resourceParts</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="mi">1</span><span class="o">);</span> <span class="c1">// don&#39;t support more complex URIs</span>
+    <span class="k">if</span><span class="o">(</span><span class="n">lastSegment</span> <span class="k">instanceof</span> <span class="n">UriResourceNavigation</span><span class="o">){</span>
+        <span class="n">UriResourceNavigation</span> <span class="n">uriResourceNavigation</span> <span class="o">=</span> <span class="o">(</span><span class="n">UriResourceNavigation</span><span class="o">)</span><span class="n">lastSegment</span><span class="o">;</span>
+        <span class="n">EdmNavigationProperty</span> <span class="n">edmNavigationProperty</span> <span class="o">=</span> <span class="n">uriResourceNavigation</span><span class="o">.</span><span class="na">getProperty</span><span class="o">();</span>
+        <span class="n">EdmEntityType</span> <span class="n">targetEntityType</span> <span class="o">=</span> <span class="n">edmNavigationProperty</span><span class="o">.</span><span class="na">getType</span><span class="o">();</span>
+        <span class="n">responseEdmEntitySet</span> <span class="o">=</span> <span class="n">Util</span><span class="o">.</span><span class="na">getNavigationTargetEntitySet</span><span class="o">(</span><span class="n">startEdmEntitySet</span><span class="o">,</span> <span class="n">edmNavigationProperty</span><span class="o">);</span>
+
+        <span class="c1">// 2nd: fetch the data from backend</span>
+        <span class="c1">// first fetch the entity where the first segment of the URI points to</span>
+        <span class="c1">// e.g. Categories(3)/Products first find the single entity: Category(3)</span>
+        <span class="n">List</span><span class="o">&lt;</span><span class="n">UriParameter</span><span class="o">&gt;</span> <span class="n">keyPredicates</span> <span class="o">=</span> <span class="n">uriResourceEntitySet</span><span class="o">.</span><span class="na">getKeyPredicates</span><span class="o">();</span>
+        <span class="n">Entity</span> <span class="n">sourceEntity</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="na">readEntityData</span><span class="o">(</span><span class="n">startEdmEntitySet</span><span class="o">,</span> <span class="n">keyPredicates</span><span class="o">);</span>
+        <span class="c1">// error handling for e.g.  DemoService.svc/Categories(99)/Products</span>
+        <span class="k">if</span><span class="o">(</span><span class="n">sourceEntity</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;Entity not 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="c1">// then fetch the entity collection where the entity navigates to</span>
+        <span class="n">responseEntityCollection</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="na">getRelatedEntityCollection</span><span class="o">(</span><span class="n">sourceEntity</span><span class="o">,</span> <span class="n">targetEntityType</span><span class="o">);</span>
+    <span class="o">}</span>
+<span class="o">}</span><span class="k">else</span><span class="o">{</span> <span class="c1">// this would be the case for e.g. Products(1)/Category/Products</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 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">ROOT</span><span class="o">);</span>
+<span class="o">}</span>
+
+<span class="c1">// 3rd: create and configure a serializer</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">entitySet</span><span class="o">(</span><span class="n">responseEdmEntitySet</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="n">EdmEntityType</span> <span class="n">edmEntityType</span> <span class="o">=</span> <span class="n">responseEdmEntitySet</span><span class="o">.</span><span class="na">getEntityType</span><span class="o">();</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">ODataFormat</span><span class="o">.</span><span class="na">fromContentType</span><span class="o">(</span><span class="n">responseFormat</span><span class="o">));</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="k">this</span><span class="o">.</span><span class="na">srvMetadata</span><span class="o">,</span> <span class="n">edmEntityType</span><span class="o">,</span> <span class="n">responseEntityCollection</span><span class="o">,</span> <span class="n">opts</span><span class="o">);</span>
+
+<span class="c1">// 4th: configure the response object: set the body, headers and status code</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>
 </pre></div>
 
 
@@ -567,10 +563,10 @@ As per design, a product can only belong
 
 
 <p>So when the user follows the navigation property in order to display the product category, he expects a response that contains only one entry.
-This means that we have to do the implementation in the <em>EntityProcessor</em>.</p>
-<p>Open the class <em>myservice.mynamespace.service.DemoEntityProcessor.java</em></p>
+This means that we have to do the implementation in the <code>EntityProcessor</code>.</p>
+<p>Open the class <code>myservice.mynamespace.service.DemoEntityProcessor.java</code></p>
 <p>As usual, we first have to analyze the URI.
-Just like we did in the <em>EntityCollectionProcessor</em>, we have to distinguish between navigation and “normal” read of an entity:</p>
+Just like we did in the <code>EntityCollectionProcessor</code>, we have to distinguish between navigation and “normal” read of an entity:</p>
 <div class="codehilite"><pre><span class="k">if</span><span class="o">(</span><span class="n">segmentCount</span> <span class="o">==</span> <span class="mi">1</span><span class="o">){</span>
     <span class="c1">// in case of directly adressing of an entity</span>
 <span class="o">}</span><span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">segmentCount</span> <span class="o">==</span> <span class="mi">2</span><span class="o">){</span>
@@ -579,10 +575,10 @@ Just like we did in the <em>EntityCollec
 </pre></div>
 
 
-<p>In the following section, we’ll focus on the navigation case only.
+<p>In the following section, we will focus on the navigation case only.
 In our example, our task is to find the category of a chosen product.
 Again, we have to first fetch the chosen product (first URI segment) from our database-mock and in a second step, we have to ask our database-mock for the corresponding category.
-This final entity is then serialized and set as response body for the <em>readEntity</em> method, which we’re implementing.</p>
+This final entity is then serialized and set as response body for the <code>readEntity()</code> method, which we’re implementing.</p>
 <p><strong>A) get the data for the first URI segment</strong></p>
 <p>In our example, we have to perform a read operation for retrieving the product with ID 1: <a href="http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category">http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category</a></p>
 <p>The code is the same like in the previous chapter (to-many navigation):</p>
@@ -599,7 +595,7 @@ Therefore, we invoke our helper method a
 </pre></div>
 
 
-<p>Before we can serialize the <em>responseEntity</em>, we have to retrieve the <em>EdmEntitySet</em> that corresponds to the response entity, because we need it for building the ContextURL.</p>
+<p>Before we can serialize the <code>responseEntity</code>, we have to retrieve the <code>EdmEntitySet</code> that corresponds to the response entity, because we need it for building the ContextURL.</p>
 <p>The procedure is the same like in the chapter above, where we treated the to-many navigation:</p>
 <div class="codehilite"><pre><span class="n">EdmNavigationProperty</span> <span class="n">edmNavigationProperty</span> <span class="o">=</span> <span class="n">uriResourceNavigation</span><span class="o">.</span><span class="na">getProperty</span><span class="o">();</span>
 <span class="n">responseEdmEntityType</span> <span class="o">=</span> <span class="n">edmNavigationProperty</span><span class="o">.</span><span class="na">getType</span><span class="o">();</span>
@@ -607,7 +603,7 @@ Therefore, we invoke our helper method a
 </pre></div>
 
 
-<p>In our example, the value of the variable <em>responseEdmEntitySet</em> will be “Categories” and it will be used for building the contextURL, which will look as follows:</p>
+<p>In our example, the value of the variable <code>responseEdmEntitySet</code> will be “Categories” and it will be used for building the contextURL, which will look as follows:</p>
 <div class="codehilite"><pre>&quot;$metadata#Categories/$entity&quot;
 </pre></div>
 
@@ -615,7 +611,7 @@ Therefore, we invoke our helper method a
 <h2 id="34-implement-the-to-many-navigation-with-key-access">3.4. Implement the to-many navigation with key access<a class="headerlink" href="#34-implement-the-to-many-navigation-with-key-access" title="Permanent link">&para;</a></h2>
 <p>"Navigation with key access" means that we have a to-many navigation, like navigating from a chosen category to the list of corresponding products: <a href="http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products">http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products</a></p>
 <p>but in addition, we want to read only one of the collected products, which is directly addressed by its key:   <a href="http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products(5)">http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products(5)</a></p>
-<p>From this URL, we can assume that the <em>EntityProcessor.java</em> is the relevant place to handle this request in our code.</p>
+<p>From this URL, we can assume that the <code>EntityProcessor</code> is the relevant place to handle this request in our code.</p>
 <p>The steps to find the requested entity are:</p>
 <ol>
 <li>Do a read operation for the first segment (same as in the previous chapter)
@@ -626,12 +622,12 @@ Therefore, we invoke our helper method a
   In our example, retrieve the product with ID=5, which is contained in the collection <em>/Categories(3)/Products(5)</em></li>
 </ol>
 <p>We can assume, that our database-mock is able to perform step 2 and 3 together.</p>
-<p>In our class <em>myservice.mynamespace.service.DemoEntityProcessor.java</em>, we’ve already added the navigation capability for to-one navigation.
+<p>In our class <code>myservice.mynamespace.service.DemoEntityProcessor.java</code>, we’ve already added the navigation capability for to-one navigation.
 How can we find out that we aren’t called for a to-one navigation, but instead, we’re responding to a to-many navigation with key access?
 The difference is the “key predicate”.
 The necessary info about it can be obtained from the URI segment.
-In the first chapter, we’ve already learned that there’s a special interface responsible for navigation segments, the <em>org.apache.olingo.server.api.uri.UriResourceNavigation</em>
-It also provides a method <em>getKeyPredicates()</em>
+In the first chapter, we’ve already learned that there’s a special interface responsible for navigation segments, the <code>org.apache.olingo.server.api.uri.UriResourceNavigation</code>
+It also provides a method <code>getKeyPredicates()</code>
 We can make use of it in order to distinguish between “to-one navigation” and “navigation with key access”.
 If the call to</p>
 <div class="codehilite"><pre><span class="n">List</span><span class="o">&lt;</span><span class="n">UriParmeter</span><span class="o">&gt;</span> <span class="n">navKeyPredicates</span> <span class="o">=</span> <span class="n">uriResourceNavigation</span><span class="o">.</span><span class="na">getKeyPredicates</span><span class="o">();</span>
@@ -642,8 +638,8 @@ If the call to</p>
 This to-one navigation has been explained in the chapter 3.3. above.
 If  the service request is like
 /Categories(3)/Products(5)
-then the method <em>getKeyPredicates()</em> will return a list of with one element that contains ID=5</p>
-<p>In our implementation of the <em>EntityProcessor</em>, we add the following code:</p>
+then the method <code>getKeyPredicates()</code> will return a list of with one element that contains ID=5</p>
+<p>In our implementation of the <code>EntityProcessor</code>, we add the following code:</p>
 <div class="codehilite"><pre><span class="n">List</span><span class="o">&lt;</span><span class="n">UriParameter</span><span class="o">&gt;</span> <span class="n">navKeyPredicates</span> <span class="o">=</span> <span class="n">uriResourceNavigation</span><span class="o">.</span><span class="na">getKeyPredicates</span><span class="o">();</span>
 <span class="k">if</span><span class="o">(</span><span class="n">navKeyPredicates</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">()){</span>
     <span class="n">responseEntity</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="na">getRelatedEntity</span><span class="o">(</span><span class="n">sourceEntity</span><span class="o">,</span> <span class="n">responseEdmEntityType</span><span class="o">);</span>
@@ -662,16 +658,11 @@ The new helper method</p>
 </pre></div>
 
 
-<p>will take care of getting the collection of products (<em>responseEntityType</em>) that are in scope of the chosen category (<em>sourceEntity</em>) and will then pick the requested product, based on the given key (<em>navKeyPredicates</em>).</p>
-<p>One last thing to consider:
-As we mentioned above, the user of our service is expected to specify a key of a product that is contained in the collection of products that is addressed by e.g.
-/Categories(3)/Products
-e.g.
-/Categories(3)/Products(5)
-But he might specify a product ID that is existing, but not valid for the addressed navigation.
-e.g.
-/Categories(3)/Products(1)
-With other words: it is not valid to navigate from category "Monitors" to a product like "Notebook Basic 15"</p>
+<p>will take care of getting the collection of products (<code>responseEntityType</code>) that are in scope of the chosen category (<code>sourceEntity</code>) and will then pick the requested product, based on the given key (<code>navKeyPredicates</code>).</p>
+<p>One last thing to consider:<br />
+As we mentioned above, the user of our service is expected to specify a key of a product that is contained in the collection of products (e.g. <em>/Categories(3)/Products</em>) that is addressed by e.g. <em>/Categories(3)/Products(5)</em>.</p>
+<p>But he might specify a product ID that is existing, but not valid for the addressed navigation e.g. <em>/Categories(3)/Products(1)</em>.</p>
+<p>With other words: it is not valid to navigate from category "Monitors" to a product like "Notebook Basic 15"</p>
 <p>If this is the case, we have to throw an appropriate exception.
 However, in our simple example we’re satisfied with simply checking if an entity was found at all:</p>
 <div class="codehilite"><pre><span class="k">if</span><span class="o">(</span><span class="n">responseEntity</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
@@ -690,8 +681,8 @@ E.g. in our example, the following URI s
 Categories(3)/Products(1)
 As we know, Categories(3) is “Monitors” and Product(1) is a “Notebook”</p>
 <p>That’s it.
-We don’t need to do an additional effort to retrieve the <em>EdmEntitySet</em> for the ContextURL, because this has already been implemented in our <em>DemoEntityProcessor</em> in the context of the previous chapter 3.3.</p>
-<p>So now we can finally have a look at the full implementation of the <em>readEntity()</em> method, the covers both the cases of chapter 3.3. and 3.4.</p>
+We don’t need to do an additional effort to retrieve the <code>EdmEntitySet</code> for the ContextURL, because this has already been implemented in our <code>DemoEntityProcessor</code> in the context of the previous chapter 3.3.</p>
+<p>So now we can finally have a look at the full implementation of the <code>readEntity()</code> method, the covers both the cases of chapter 3.3. and 3.4.</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>
 
@@ -826,7 +817,8 @@ Check the <em>Links</em> section for mor
 <li>Tutorial OData V4 service part 2: <a href="/doc/odata4/tutorials/readep/tutorial_readep.html">Read Entity, Read Property</a> | <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>)  </li>
 <li>Tutorial OData V4 service part 3: <a href="/doc/odata4/tutorials/write/tutorial_write.html">Write (Create, Update, Delete Entity)</a> | <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Write.zip">sample project zip</a> (<a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Write.zip.md5">md5</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Write.zip.sha512">sha512</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Write.zip.asc">pgp</a>)  </li>
 <li>Tutorial OData V4 service, part 4: <a href="/doc/odata4/tutorials/navigation/tutorial_navigation.html">Navigation (this page)</a> | <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip">sample project zip</a> (<a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip.md5">md5</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip.sha512">sha512</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip.asc">pgp</a>)</li>
-<li>Tutorial OData V4 service, part 5: System Query Options  (to be announced)</li>
+<li>Tutorial OData V4 service, part 5: System Query Options  (to be announced)
+<!--  --></li>
 </ul>
 <h3 id="further-reading">Further reading<a class="headerlink" href="#further-reading" title="Permanent link">&para;</a></h3>
 <ul>



Mime
View raw message