Added: 
websites/staging/olingo/trunk/content/doc/odata4/tutorials/read_expand.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/read_expand.html 
(added)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/read_expand.html 
Tue Sep 16 12:34:18 2014
@@ -0,0 +1,320 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html lang="en">
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="description" content="Apache Olingo provides libraries which 
enable developers to implement OData producers and OData consumers. The 
available OData Java library implements OData version 2.0. In future on goal is 
to provide an OData 4.0 compliant library once the OData standard is published 
at OASIS. The focus within the community is currently on the Java technology 
but it is up to the community to discuss if other environments find interest.">
+    <meta name="author" content="">
+    <link rel="icon" href="/favicon.ico">
+    <title>
+      Apache Olingo
+    </title><!-- Bootstrap core CSS -->
+    <link href="/css/bootstrap.css" rel="stylesheet" type="text/css"><!-- 
Custom styles for this template -->
+    <link href="/css/navbar.css" rel="stylesheet" type="text/css"><!-- Just 
for debugging purposes. Don't actually copy these 2 lines! -->
+    <link href="/css/offcanvas.css" rel="stylesheet" type="text/css"><!-- 
Custom styles for this template -->
+    <link rel="stylesheet" href="/css/main.css">
+    <!--[if lt IE 9]><script 
src="/js/ie8-responsive-file-warning.js"></script><![endif]-->
+
+    <script src="/js/ie-emulation-modes-warning.js" type="text/javascript">
+</script><!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
+
+    <script src="/js/ie10-viewport-bug-workaround.js" type="text/javascript">
+</script><!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and 
media queries -->
+    <!--[if lt IE 9]>
+      <script src="/js/html5shiv.min.js"></script>
+      <script src="/js/respond.min.js"></script>
+    <![endif]-->
+  </head>
+
+  <body>
+    <div class="container">
+      <!-- Static navbar -->
+      <div class="navbar navbar-default" role="navigation">
+        <div class="container-fluid">
+          <div class="navbar-header">
+            <button type="button" class="navbar-toggle" data-toggle="collapse" 
data-target=".navbar-collapse">
+              <span class="sr-only">Toggle navigation</span>
+             <span class="icon-bar"></span>
+             <span class="icon-bar"></span>
+             <span class="icon-bar"></span>
+            </button>
+              <img class="navbar-brand" src="/img/OlingoOrangeTM.png" 
style="width:62px;" >
+              <a class="navbar-brand" href="#">Apache Olingo™</a>
+          </div>
+          <div class="navbar-collapse collapse">
+            <ul class="nav navbar-nav">
+
+              <li><a href="/">Home</a></li>
+              <li class="dropdown">
+                  <a href="#" class="dropdown-toggle" 
data-toggle="dropdown">ASF <b class="caret"></b></a>
+                  <ul class="dropdown-menu">
+                      <li><a href="http://www.apache.org/foundation/";>ASF 
Home</a></li>
+                      <li><a 
href="http://projects.apache.org/";>Projects</a></li>
+                      <li><a href="http://people.apache.org/";>People</a></li>
+                      <li><a 
href="http://www.apache.org/foundation/getinvolved.html";>Get Involved</a></li>
+                      <li><a 
href="http://www.apache.org/dyn/closer.cgi";>Download</a></li>
+                      <li><a 
href="http://www.apache.org/security/";>Security</a></li>
+                      <li><a 
href="http://www.apache.org/foundation/sponsorship.html";>Support Apache</a></li>
+                  </ul>
+              </li>
+
+              <li><a href="http://www.apache.org/licenses/";>License</a></li>
+
+              <li class="dropdown">
+                  <a href="#" class="dropdown-toggle" 
data-toggle="dropdown">Download <b class="caret"></b></a>
+                  <ul class="dropdown-menu">
+                      <li><a href="/doc/odata2/download.html">Download OData 
2.0 Java</a></li>
+                      <li><a href="/doc/javascript/download.html">Download 
OData 4.0 JavaScript</a></li>
+                  </ul>
+              </li>
+
+              <li class="dropdown">
+                  <a href="#" class="dropdown-toggle" 
data-toggle="dropdown">Documentation <b class="caret"></b></a>
+                  <ul class="dropdown-menu">
+                    <li><a href="/doc/odata2/index.html">Documentation OData 
2.0 Java</a></li>
+                    <li><a href="/doc/javascript/index.html">Documentation 
OData 4.0 JavaScript</a></li>
+                  </ul>
+              </li>
+              <li><a href="/support.html">Support</a></li>
+
+            </ul>
+
+                         <img class="navbar-right" height="50px" 
src="/img/asf-logo.gif">
+
+                       </div><!--/.nav-collapse -->
+        </div><!--/.container-fluid -->
+      </div><!-- Main component for a primary marketing message or call to 
action --><h1 id="read-scenario-read-with-expand">Read Scenario - Read with 
$expand</h1>
+<hr />
+<h3 id="how-to-guide-extend-basic-read-scenario-with-support-for-expand">How 
To Guide - Extend basic read scenario with support for $expand</h3>
+<p>This How To Guide shows how to extend the basic read scenario with support 
for the $expand system query option.
+It shows how to call the <code>EntityProvider.writeEntry(...)</code> and 
<code>EntityProvider.writeEntrySet(...)</code> methods with the necessary 
<code>EntityProviderWriteProperties</code> set and how to implement the 
necessary <code>OnWriteEntryContent OnWriteFeedContent</code> callbacks.</p>
+<h3 id="prerequisites">Prerequisites</h3>
+<p>Setup of <a href="basicread">Basic Read Scenario</a></p>
+<h3 id="shortcut">Shortcut</h3>
+<p>If you like to directly experiment with the results of the extented basic 
read scenario, you can use this shortcut: </p>
+<ul>
+<li>Download and unzip <a 
href="apache-olingo-tutorial-adv_read_expand.zip">Olingo Tutorial 'Basic Read 
with $expand extension' Project</a> to your local drive which is your OData 
Tutorial project folder (referenced as <code>$ODATA_PROJECT_HOME</code> in the 
tutorial).</li>
+<li>Start the command line tool and execute the following command in the 
folder <code>$ODATA_PROJECT_HOME</code> <ul>
+<li><code>mvn eclipse:eclipse clean install</code> </li>
+</ul>
+</li>
+<li>Go into Eclipse and import the project into your workspace by... <ul>
+<li>Menu <em>File -&gt; Import</em>... </li>
+<li><em>Existing projects into workspace</em>, then choose the 
<code>$ODATA_PROJECT_HOME</code> folder </li>
+<li>Select both projects <em>olingo.odata2.sample.service</em> and 
<em>olingo.odata2.sample.web</em> and press <em>Finish</em>. </li>
+</ul>
+</li>
+</ul>
+<h3 id="set-up-your-development-project">Set Up your development project</h3>
+<p>If <a href="basicread">Basic Read Scenario</a> is already set up there is 
nothing additional to do. Otherwise please refer to the Prerequisites section 
of the <a href="basicread">Basic Read Scenario</a>.</p>
+<h3 id="extend-basic-read-scenario">Extend Basic Read Scenario</h3>
+<p>The steps to extend the basic read with $expand support for the Car and 
Manufacturer entities (not entity sets) are to provide the expanded data via 
ODataCallbacks and register these for the corresponding navigation properties. 
</p>
+<h3 
id="implement-onwriteentrycontent-and-onwritefeedcontent-callbacks">Implement 
OnWriteEntryContent and OnWriteFeedContent callbacks</h3>
+<p>To support <code>$expand</code> for a single entry the interface 
<code>org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent</code> must 
be implemented. This provides the method <code>WriteEntryCallbackResult 
retrieveEntryResult(WriteEntryCallbackContext context) throws 
ODataApplicationException;</code> which is called during processing from the 
<code>EntityProvider</code> to receive the necessary data which than is inlined 
in the response.</p>
+<p>In our sample we create a class <code>MyCallback</code> which implements 
<code>org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent</code> in 
following way:</p>
+<h5 id="sample-code">Sample Code</h5>
+<div class="codehilite"><pre><span class="nd">@Override</span>
+<span class="kd">public</span> <span class="n">WriteEntryCallbackResult</span> 
<span class="nf">retrieveEntryResult</span><span class="o">(</span><span 
class="n">WriteEntryCallbackContext</span> <span class="n">context</span><span 
class="o">)</span> <span class="kd">throws</span> <span 
class="n">ODataApplicationException</span> <span class="o">{</span>
+<span class="n">WriteEntryCallbackResult</span> <span class="n">result</span> 
<span class="o">=</span> <span class="k">new</span> <span 
class="n">WriteEntryCallbackResult</span><span class="o">();</span>
+
+  <span class="k">try</span> <span class="o">{</span>
+    <span class="k">if</span> <span class="o">(</span><span 
class="n">isNavigationFromTo</span><span class="o">(</span><span 
class="n">context</span><span class="o">,</span> <span 
class="n">ENTITY_SET_NAME_CARS</span><span class="o">,</span> <span 
class="n">ENTITY_NAME_MANUFACTURER</span><span class="o">))</span> <span 
class="o">{</span>
+    <span class="n">EntityProviderWriteProperties</span> <span 
class="n">inlineProperties</span> <span class="o">=</span> <span 
class="n">EntityProviderWriteProperties</span><span class="o">.</span><span 
class="na">serviceRoot</span><span class="o">(</span><span 
class="n">serviceRoot</span><span class="o">)</span>
+        <span class="o">.</span><span class="na">expandSelectTree</span><span 
class="o">(</span><span class="n">context</span><span class="o">.</span><span 
class="na">getCurrentExpandSelectTreeNode</span><span class="o">())</span>
+        <span class="o">.</span><span class="na">build</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">Object</span><span class="o">&gt;</span> <span class="n">keys</span> 
<span class="o">=</span> <span class="n">context</span><span 
class="o">.</span><span class="na">extractKeyFromEntryData</span><span 
class="o">();</span>
+      <span class="n">Integer</span> <span class="n">carId</span> <span 
class="o">=</span> <span class="o">(</span><span class="n">Integer</span><span 
class="o">)</span> <span class="n">keys</span><span class="o">.</span><span 
class="na">get</span><span class="o">(</span><span 
class="s">&quot;Id&quot;</span><span class="o">);</span>
+      <span class="n">result</span><span class="o">.</span><span 
class="na">setEntryData</span><span class="o">(</span><span 
class="n">dataStore</span><span class="o">.</span><span 
class="na">getManufacturerFor</span><span class="o">(</span><span 
class="n">carId</span><span class="o">));</span>
+      <span class="n">result</span><span class="o">.</span><span 
class="na">setInlineProperties</span><span class="o">(</span><span 
class="n">inlineProperties</span><span class="o">);</span>
+    <span class="o">}</span>
+  <span class="o">}</span> <span class="k">catch</span> <span 
class="o">(</span><span class="n">EdmException</span> <span 
class="n">e</span><span class="o">)</span> <span class="o">{</span>
+  <span class="c1">// TODO: should be handled and not only logged</span>
+  <span class="n">LOG</span><span class="o">.</span><span 
class="na">error</span><span class="o">(</span><span class="s">&quot;Error in 
$expand handling.&quot;</span><span class="o">,</span> <span 
class="n">e</span><span class="o">);</span>
+  <span class="o">}</span> <span class="k">catch</span> <span 
class="o">(</span><span class="n">EntityProviderException</span> <span 
class="n">e</span><span class="o">)</span> <span class="o">{</span>
+  <span class="c1">// TODO: should be handled and not only logged</span>
+  <span class="n">LOG</span><span class="o">.</span><span 
class="na">error</span><span class="o">(</span><span class="s">&quot;Error in 
$expand handling.&quot;</span><span class="o">,</span> <span 
class="n">e</span><span class="o">);</span>
+  <span class="o">}</span>
+
+  <span class="k">return</span> <span class="n">result</span><span 
class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Within this method we first check if the source entity and navigation 
property are correct for our case (via the method 
<code>isNavigationFromTo(...):boolean)</code>, then we create the 
<code>EntityProviderWriteProperties</code> with the new (current) 
<code>ExpandSelectTreeNode</code>, receive the data from our 
<code>DataStore</code> and put all into the result which then will be further 
processed by the <code>EntityProvider</code>.</p>
+<h3 id="implementation-for-expand-for-an-entity-set">Implementation for 
$expand for an entity set</h3>
+<p>To support <code>$expand</code> for a feed of entries (entity set) the 
interface 
<code>org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent</code> must 
be implemented. These provides the method <code>WriteFeedCallbackResult 
retrieveFeedResult(WriteFeedCallbackContext context) throws 
ODataApplicationException;</code> which is called during processing from the 
<code>EntityProvider</code> to receive the necessary data which than is inlined 
in the response.</p>
+<p>It is possible to create an additional callback class but for convenience 
we expand our already created callback (<code>MyCallback</code>) to implement 
<code>org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent</code> and 
provide the method implementation in following way:</p>
+<h5 id="sample-code_1">Sample Code</h5>
+<div class="codehilite"><pre><span class="nd">@Override</span>
+<span class="kd">public</span> <span class="n">WriteFeedCallbackResult</span> 
<span class="nf">retrieveFeedResult</span><span class="o">(</span><span 
class="n">WriteFeedCallbackContext</span> <span class="n">context</span><span 
class="o">)</span> <span class="kd">throws</span> <span 
class="n">ODataApplicationException</span> <span class="o">{</span>
+<span class="n">WriteFeedCallbackResult</span> <span class="n">result</span> 
<span class="o">=</span> <span class="k">new</span> <span 
class="n">WriteFeedCallbackResult</span><span class="o">();</span>
+  <span class="k">try</span> <span class="o">{</span>
+    <span class="k">if</span><span class="o">(</span><span 
class="n">isNavigationFromTo</span><span class="o">(</span><span 
class="n">context</span><span class="o">,</span> <span 
class="n">ENTITY_SET_NAME_MANUFACTURERS</span><span class="o">,</span> <span 
class="n">ENTITY_SET_NAME_CARS</span><span class="o">))</span> <span 
class="o">{</span>
+    <span class="n">EntityProviderWriteProperties</span> <span 
class="n">inlineProperties</span> <span class="o">=</span> <span 
class="n">EntityProviderWriteProperties</span><span class="o">.</span><span 
class="na">serviceRoot</span><span class="o">(</span><span 
class="n">serviceRoot</span><span class="o">)</span>
+        <span class="o">.</span><span class="na">expandSelectTree</span><span 
class="o">(</span><span class="n">context</span><span class="o">.</span><span 
class="na">getCurrentExpandSelectTreeNode</span><span class="o">())</span>
+        <span class="o">.</span><span class="na">selfLink</span><span 
class="o">(</span><span class="n">context</span><span class="o">.</span><span 
class="na">getSelfLink</span><span class="o">())</span>
+        <span class="o">.</span><span class="na">build</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">Object</span><span class="o">&gt;</span> <span class="n">keys</span> 
<span class="o">=</span> <span class="n">context</span><span 
class="o">.</span><span class="na">extractKeyFromEntryData</span><span 
class="o">();</span>
+      <span class="n">Integer</span> <span class="n">manufacturerId</span> 
<span class="o">=</span> <span class="o">(</span><span 
class="n">Integer</span><span class="o">)</span> <span 
class="n">keys</span><span class="o">.</span><span class="na">get</span><span 
class="o">(</span><span class="s">&quot;Id&quot;</span><span class="o">);</span>
+      <span class="n">result</span><span class="o">.</span><span 
class="na">setFeedData</span><span class="o">(</span><span 
class="n">dataStore</span><span class="o">.</span><span 
class="na">getCarsFor</span><span class="o">(</span><span 
class="n">manufacturerId</span><span class="o">));</span>
+      <span class="n">result</span><span class="o">.</span><span 
class="na">setInlineProperties</span><span class="o">(</span><span 
class="n">inlineProperties</span><span class="o">);</span>
+    <span class="o">}</span>
+  <span class="o">}</span> <span class="k">catch</span> <span 
class="o">(</span><span class="n">EdmException</span> <span 
class="n">e</span><span class="o">)</span> <span class="o">{</span>
+  <span class="c1">// TODO: should be handled and not only logged</span>
+  <span class="n">LOG</span><span class="o">.</span><span 
class="na">error</span><span class="o">(</span><span class="s">&quot;Error in 
$expand handling.&quot;</span><span class="o">,</span> <span 
class="n">e</span><span class="o">);</span>
+  <span class="o">}</span> <span class="k">catch</span> <span 
class="o">(</span><span class="n">EntityProviderException</span> <span 
class="n">e</span><span class="o">)</span> <span class="o">{</span>
+  <span class="c1">// TODO: should be handled and not only logged</span>
+  <span class="n">LOG</span><span class="o">.</span><span 
class="na">error</span><span class="o">(</span><span class="s">&quot;Error in 
$expand handling.&quot;</span><span class="o">,</span> <span 
class="n">e</span><span class="o">);</span>
+  <span class="o">}</span>
+  <span class="k">return</span> <span class="n">result</span><span 
class="o">;</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Within this method we first check if the source entity and navigation 
property are correct for our case (via the method 
<code>isNavigationFromTo(...):boolean)</code>, then we create the 
<code>EntityProviderWriteProperties</code> with the new (current) 
<code>ExpandSelectTreeNode</code>, receive the data from our 
<code>DataStore</code> and put all into the result which then will be further 
processed by the <code>EntityProvider</code>.</p>
+<p>This example shows that the basic callback logic between 
<code>OnWriteEntryConten</code>t and <code>OnWriteFeedContent</code> is very 
similar. Validation of current element (optional), preparing of 
<code>EntityProviderWriteProperties</code>, receive of data and putting all 
together into corresponding result object 
(<code>WriteEntryCallbackResult</code> or 
<code>WriteFeedCallbackResult</code>).</p>
+<p>To improve code readability the 
<code>isNavigationFromTo(...):boolean</code> method was also added to the 
class. The method is used to check if the retrieved request is related to given 
entity set and navigation:</p>
+<h4 id="sample-code_2">Sample Code</h4>
+<div class="codehilite"><pre><span class="kd">private</span> <span 
class="kt">boolean</span> <span class="nf">isNavigationFromTo</span><span 
class="o">(</span><span class="n">WriteCallbackContext</span> <span 
class="n">context</span><span class="o">,</span> <span class="n">String</span> 
<span class="n">entitySetName</span><span class="o">,</span> <span 
class="n">String</span> <span class="n">navigationPropertyName</span><span 
class="o">)</span> <span class="kd">throws</span> <span 
class="n">EdmException</span> <span class="o">{</span>
+  <span class="k">if</span><span class="o">(</span><span 
class="n">entitySetName</span> <span class="o">==</span> <span 
class="kc">null</span> <span class="o">||</span> <span 
class="n">navigationPropertyName</span> <span class="o">==</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+  <span class="k">return</span> <span class="kc">false</span><span 
class="o">;</span>
+  <span class="o">}</span>
+  <span class="n">EdmEntitySet</span> <span class="n">sourceEntitySet</span> 
<span class="o">=</span> <span class="n">context</span><span 
class="o">.</span><span class="na">getSourceEntitySet</span><span 
class="o">();</span>
+  <span class="n">EdmNavigationProperty</span> <span 
class="n">navigationProperty</span> <span class="o">=</span> <span 
class="n">context</span><span class="o">.</span><span 
class="na">getNavigationProperty</span><span class="o">();</span>
+  <span class="k">return</span> <span class="n">entitySetName</span><span 
class="o">.</span><span class="na">equals</span><span class="o">(</span><span 
class="n">sourceEntitySet</span><span class="o">.</span><span 
class="na">getName</span><span class="o">())</span> <span 
class="o">&amp;&amp;</span> <span class="n">navigationPropertyName</span><span 
class="o">.</span><span class="na">equals</span><span class="o">(</span><span 
class="n">navigationProperty</span><span class="o">.</span><span 
class="na">getName</span><span class="o">());</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h3 id="extend-odatasingleprocessorreadentity">Extend 
ODataSingleProcessor.readEntity(...)</h3>
+<p>The necessary callbacks (<code>MyCallback</code> class) now has to be 
registered during the corresponding <code>readEntity(...)</code> call. 
Therefore we first create a map with the property name as key and the according 
callback as value. Additional we need to create the 
<code>ExpandSelectTreeNode</code> based on current element position. Both then 
have to be set in the <code>EntityProviderWritePropertiesBuilder</code>. </p>
+<p>The following code show the few lines we need for extending the read of a 
car with its expanded manufacturer.</p>
+<div class="codehilite"><pre><span class="c1">// create and register 
callback</span>
+<span class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">ODataCallback</span><span class="o">&gt;</span> <span 
class="n">callbacks</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">HashMap</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">ODataCallback</span><span class="o">&gt;();</span>
+<span class="n">callbacks</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">ENTITY_NAME_MANUFACTURER</span><span class="o">,</span> <span 
class="k">new</span> <span class="n">MyCallback</span><span 
class="o">(</span><span class="n">dataStore</span><span class="o">,</span> 
<span class="n">serviceRoot</span><span class="o">));</span>
+<span class="n">ExpandSelectTreeNode</span> <span 
class="n">expandSelectTreeNode</span> <span class="o">=</span> <span 
class="n">UriParser</span><span class="o">.</span><span 
class="na">createExpandSelectTree</span><span class="o">(</span><span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getSelect</span><span class="o">(),</span> <span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getExpand</span><span class="o">());</span>
+<span class="n">propertiesBuilder</span><span class="o">.</span><span 
class="na">expandSelectTree</span><span class="o">(</span><span 
class="n">expandSelectTreeNode</span><span class="o">).</span><span 
class="na">callbacks</span><span class="o">(</span><span 
class="n">callbacks</span><span class="o">);</span>
+</pre></div>
+
+
+<p>The following code show the few lines we need for extending the read of a 
manufacturer with its expanded cars.</p>
+<div class="codehilite"><pre><span class="c1">// create and register 
callback</span>
+<span class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">ODataCallback</span><span class="o">&gt;</span> <span 
class="n">callbacks</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">HashMap</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">ODataCallback</span><span class="o">&gt;();</span>
+<span class="n">callbacks</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">ENTITY_SET_NAME_CARS</span><span class="o">,</span> <span 
class="k">new</span> <span class="n">MyCallback</span><span 
class="o">(</span><span class="n">dataStore</span><span class="o">,</span> 
<span class="n">serviceRoot</span><span class="o">));</span>
+<span class="n">ExpandSelectTreeNode</span> <span 
class="n">expandSelectTreeNode</span> <span class="o">=</span> <span 
class="n">UriParser</span><span class="o">.</span><span 
class="na">createExpandSelectTree</span><span class="o">(</span><span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getSelect</span><span class="o">(),</span> <span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getExpand</span><span class="o">());</span>
+<span class="n">propertiesBuilder</span><span class="o">.</span><span 
class="na">expandSelectTree</span><span class="o">(</span><span 
class="n">expandSelectTreeNode</span><span class="o">).</span><span 
class="na">callbacks</span><span class="o">(</span><span 
class="n">callbacks</span><span class="o">);</span>
+</pre></div>
+
+
+<p>The complete <code>readEntity(...)</code> method should now look like:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span 
class="n">ODataResponse</span> <span class="nf">readEntity</span><span 
class="o">(</span><span class="n">GetEntityUriInfo</span> <span 
class="n">uriInfo</span><span class="o">,</span> <span class="n">String</span> 
<span class="n">contentType</span><span class="o">)</span> <span 
class="kd">throws</span> <span class="n">ODataException</span> <span 
class="o">{</span>
+
+  <span class="k">if</span> <span class="o">(</span><span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getNavigationSegments</span><span class="o">().</span><span 
class="na">size</span><span class="o">()</span> <span class="o">==</span> <span 
class="mi">0</span><span class="o">)</span> <span class="o">{</span>
+  <span class="n">EdmEntitySet</span> <span class="n">entitySet</span> <span 
class="o">=</span> <span class="n">uriInfo</span><span class="o">.</span><span 
class="na">getStartEntitySet</span><span class="o">();</span>
+
+    <span class="k">if</span> <span class="o">(</span><span 
class="n">ENTITY_SET_NAME_CARS</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">entitySet</span><span class="o">.</span><span 
class="na">getName</span><span class="o">()))</span> <span class="o">{</span>
+    <span class="kt">int</span> <span class="n">id</span> <span 
class="o">=</span> <span class="n">getKeyValue</span><span 
class="o">(</span><span class="n">uriInfo</span><span class="o">.</span><span 
class="na">getKeyPredicates</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">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">Object</span><span class="o">&gt;</span> <span class="n">data</span> 
<span class="o">=</span> <span class="n">dataStore</span><span 
class="o">.</span><span class="na">getCar</span><span class="o">(</span><span 
class="n">id</span><span class="o">);</span>
+
+      <span class="k">if</span> <span class="o">(</span><span 
class="n">data</span> <span class="o">!=</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+      <span class="n">URI</span> <span class="n">serviceRoot</span> <span 
class="o">=</span> <span class="n">getContext</span><span 
class="o">().</span><span class="na">getPathInfo</span><span 
class="o">().</span><span class="na">getServiceRoot</span><span 
class="o">();</span>
+      <span class="n">ODataEntityProviderPropertiesBuilder</span> <span 
class="n">propertiesBuilder</span> <span class="o">=</span> <span 
class="n">EntityProviderWriteProperties</span><span class="o">.</span><span 
class="na">serviceRoot</span><span class="o">(</span><span 
class="n">serviceRoot</span><span class="o">);</span>
+
+        <span class="c1">// create and register callback</span>
+      <span class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">ODataCallback</span><span class="o">&gt;</span> <span 
class="n">callbacks</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">HashMap</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">ODataCallback</span><span class="o">&gt;();</span>
+      <span class="n">callbacks</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">ENTITY_NAME_MANUFACTURER</span><span class="o">,</span> <span 
class="k">new</span> <span class="n">MyCallback</span><span 
class="o">(</span><span class="n">dataStore</span><span class="o">,</span> 
<span class="n">serviceRoot</span><span class="o">));</span>
+      <span class="n">ExpandSelectTreeNode</span> <span 
class="n">expandSelectTreeNode</span> <span class="o">=</span> <span 
class="n">UriParser</span><span class="o">.</span><span 
class="na">createExpandSelectTree</span><span class="o">(</span><span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getSelect</span><span class="o">(),</span> <span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getExpand</span><span class="o">());</span>
+        <span class="c1">//</span>
+        <span class="n">propertiesBuilder</span><span class="o">.</span><span 
class="na">expandSelectTree</span><span class="o">(</span><span 
class="n">expandSelectTreeNode</span><span class="o">).</span><span 
class="na">callbacks</span><span class="o">(</span><span 
class="n">callbacks</span><span class="o">);</span>
+
+         <span class="k">return</span> <span 
class="n">EntityProvider</span><span class="o">.</span><span 
class="na">writeEntry</span><span class="o">(</span><span 
class="n">contentType</span><span class="o">,</span> <span 
class="n">entitySet</span><span class="o">,</span> <span 
class="n">data</span><span class="o">,</span> <span 
class="n">propertiesBuilder</span><span class="o">.</span><span 
class="na">build</span><span class="o">());</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">ENTITY_SET_NAME_MANUFACTURERS</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">entitySet</span><span class="o">.</span><span 
class="na">getName</span><span class="o">()))</span> <span class="o">{</span>
+      <span class="kt">int</span> <span class="n">id</span> <span 
class="o">=</span> <span class="n">getKeyValue</span><span 
class="o">(</span><span class="n">uriInfo</span><span class="o">.</span><span 
class="na">getKeyPredicates</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">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">Object</span><span class="o">&gt;</span> <span class="n">data</span> 
<span class="o">=</span> <span class="n">dataStore</span><span 
class="o">.</span><span class="na">getManufacturer</span><span 
class="o">(</span><span class="n">id</span><span class="o">);</span>
+
+      <span class="k">if</span> <span class="o">(</span><span 
class="n">data</span> <span class="o">!=</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+        <span class="n">URI</span> <span class="n">serviceRoot</span> <span 
class="o">=</span> <span class="n">getContext</span><span 
class="o">().</span><span class="na">getPathInfo</span><span 
class="o">().</span><span class="na">getServiceRoot</span><span 
class="o">();</span>
+        <span class="n">ODataEntityProviderPropertiesBuilder</span> <span 
class="n">propertiesBuilder</span> <span class="o">=</span> <span 
class="n">EntityProviderWriteProperties</span><span class="o">.</span><span 
class="na">serviceRoot</span><span class="o">(</span><span 
class="n">serviceRoot</span><span class="o">);</span>
+
+        <span class="c1">// create and register callback</span>
+        <span class="n">Map</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">ODataCallback</span><span class="o">&gt;</span> <span 
class="n">callbacks</span> <span class="o">=</span> <span class="k">new</span> 
<span class="n">HashMap</span><span class="o">&lt;</span><span 
class="n">String</span><span class="o">,</span> <span 
class="n">ODataCallback</span><span class="o">&gt;();</span>
+        <span class="n">callbacks</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span 
class="n">ENTITY_SET_NAME_CARS</span><span class="o">,</span> <span 
class="k">new</span> <span class="n">MyCallback</span><span 
class="o">(</span><span class="n">dataStore</span><span class="o">,</span> 
<span class="n">serviceRoot</span><span class="o">));</span>
+        <span class="n">ExpandSelectTreeNode</span> <span 
class="n">expandSelectTreeNode</span> <span class="o">=</span> <span 
class="n">UriParser</span><span class="o">.</span><span 
class="na">createExpandSelectTree</span><span class="o">(</span><span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getSelect</span><span class="o">(),</span> <span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getExpand</span><span class="o">());</span>
+        <span class="c1">//</span>
+        <span class="n">propertiesBuilder</span><span class="o">.</span><span 
class="na">expandSelectTree</span><span class="o">(</span><span 
class="n">expandSelectTreeNode</span><span class="o">).</span><span 
class="na">callbacks</span><span class="o">(</span><span 
class="n">callbacks</span><span class="o">);</span>
+
+        <span class="k">return</span> <span 
class="n">EntityProvider</span><span class="o">.</span><span 
class="na">writeEntry</span><span class="o">(</span><span 
class="n">contentType</span><span class="o">,</span> <span 
class="n">entitySet</span><span class="o">,</span> <span 
class="n">data</span><span class="o">,</span> <span 
class="n">propertiesBuilder</span><span class="o">.</span><span 
class="na">build</span><span class="o">());</span>
+      <span class="o">}</span>
+    <span class="o">}</span>
+
+    <span class="k">throw</span> <span class="k">new</span> <span 
class="nf">ODataNotFoundException</span><span class="o">(</span><span 
class="n">ODataNotFoundException</span><span class="o">.</span><span 
class="na">ENTITY</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">uriInfo</span><span 
class="o">.</span><span class="na">getNavigationSegments</span><span 
class="o">().</span><span class="na">size</span><span class="o">()</span> <span 
class="o">==</span> <span class="mi">1</span><span class="o">)</span> <span 
class="o">{</span>
+    <span class="c1">//navigation first level, simplified example for 
illustration purposes only</span>
+    <span class="n">EdmEntitySet</span> <span class="n">entitySet</span> <span 
class="o">=</span> <span class="n">uriInfo</span><span class="o">.</span><span 
class="na">getTargetEntitySet</span><span class="o">();</span>
+    <span class="k">if</span> <span class="o">(</span><span 
class="n">ENTITY_SET_NAME_MANUFACTURERS</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">entitySet</span><span class="o">.</span><span 
class="na">getName</span><span class="o">()))</span> <span class="o">{</span>
+      <span class="kt">int</span> <span class="n">carKey</span> <span 
class="o">=</span> <span class="n">getKeyValue</span><span 
class="o">(</span><span class="n">uriInfo</span><span class="o">.</span><span 
class="na">getKeyPredicates</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">return</span> <span class="n">EntityProvider</span><span 
class="o">.</span><span class="na">writeEntry</span><span 
class="o">(</span><span class="n">contentType</span><span class="o">,</span> 
<span class="n">uriInfo</span><span class="o">.</span><span 
class="na">getTargetEntitySet</span><span class="o">(),</span> <span 
class="n">dataStore</span><span class="o">.</span><span 
class="na">getManufacturer</span><span class="o">(</span><span 
class="n">carKey</span><span class="o">),</span>   <span 
class="n">EntityProviderWriteProperties</span><span class="o">.</span><span 
class="na">serviceRoot</span><span class="o">(</span><span 
class="n">getContext</span><span class="o">().</span><span 
class="na">getPathInfo</span><span class="o">().</span><span 
class="na">getServiceRoot</span><span class="o">()).</span><span 
class="na">build</span><span class="o">());</span>
+    <span class="o">}</span>
+
+    <span class="k">throw</span> <span class="k">new</span> <span 
class="nf">ODataNotFoundException</span><span class="o">(</span><span 
class="n">ODataNotFoundException</span><span class="o">.</span><span 
class="na">ENTITY</span><span class="o">);</span>
+  <span class="o">}</span>
+
+  <span class="k">throw</span> <span class="k">new</span> <span 
class="nf">ODataNotImplementedException</span><span class="o">();</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Now we can test out <code>$expand</code> extension in the web 
application.</p>
+<h3 id="deploy-run-and-test-expand">Deploy, run and test $expand</h3>
+<p>Like in the basic read scenario follow these steps:</p>
+<ul>
+<li>Build your project: <code>mvn clean install</code> </li>
+<li>When build finished in Eclipse, run the Web Application via <em>Run As 
-&gt; Run on Server</em> </li>
+<li>After successful server start and deployment the following uris from the 
basic read sample work as before: <ul>
+<li>Show the Manufacturers: <a 
href="http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers";>http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers</a>
 </li>
+<li>Show one Manufacturer: <a 
href="http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)">http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)</a>
 </li>
+<li>Show the Cars: <a 
href="http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars";>http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars</a>
 </li>
+<li>Show one Car: <a 
href="http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)">http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)</a>
 </li>
+<li>Show the related Manufacturer of a Car: <a 
href="http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)/Manufacturer">http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)/Manufacturer</a>
 </li>
+<li>Show the related Cars of a Manufacturer: <a 
href="http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)/Cars">http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)/Cars</a>
 </li>
+</ul>
+</li>
+<li>And in addition we can now expand the car and manufacturer with each 
other: <ul>
+<li>Show Car with its Manufacturer: <a 
href="http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)?$expand=Manufacturer">http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)?$expand=Manufacturer
 </a></li>
+<li>Show Manufacturer with its Cars: <a 
href="http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)?$expand=Cars">http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)?$expand=Cars</a>
 </li>
+</ul>
+</li>
+</ul>
+<h3 id="further-information">Further Information</h3>
+<p>Next extension step for read scenario are read of <a 
href="read_media-resource">Media Resources</a>. </p><div align="center">
+<p>Copyright © 2013-2014, The Apache Software Foundation<br>
+                                               Apache Olingo, Olingo, Apache, 
the Apache feather, and
+                               the Apache Olingo project logo are trademarks 
of the Apache Software
+                               Foundation.</p>
+        <small><a href="/doc/odata2/privacy.html">Privacy</a></small>
+      </div>
+    </div><!-- /container -->
+    <!-- Bootstrap core JavaScript
+    ================================================== -->
+    <!-- Placed at the end of the document so the pages load faster -->
+    <script src="/js/jquery.js" type="text/javascript">
+</script>
+         <script src="/js/bootstrap.js" type="text/javascript">
+         <script src="/js/offcanvas.js" type="text/javascript">
+</script>
+        <!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
+        <script>
+            (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
+            function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
+            e=o.createElement(i);r=o.getElementsByTagName(i)[0];
+            e.src='//www.google-analytics.com/analytics.js';
+            r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
+            ga('create','UA-44963757-1');ga('send','pageview');
+        </script>
+  </body>
+</html>


Reply via email to