Author: buildbot
Date: Tue May 19 09:20:01 2015
New Revision: 951850

Log:
Staging update by buildbot for olingo

Added:
    websites/staging/olingo/trunk/content/doc/odata4/tutorials/write/
    
websites/staging/olingo/trunk/content/doc/odata4/tutorials/write/tutorial_write.html
Modified:
    websites/staging/olingo/trunk/content/   (props changed)

Propchange: websites/staging/olingo/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Tue May 19 09:20:01 2015
@@ -1 +1 @@
-1680203
+1680207

Added: 
websites/staging/olingo/trunk/content/doc/odata4/tutorials/write/tutorial_write.html
==============================================================================
--- 
websites/staging/olingo/trunk/content/doc/odata4/tutorials/write/tutorial_write.html
 (added)
+++ 
websites/staging/olingo/trunk/content/doc/odata4/tutorials/write/tutorial_write.html
 Tue May 19 09:20:01 2015
@@ -0,0 +1,444 @@
+<!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 Library
+    </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/odata4/download.html">Download OData 
4.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/odata4/index.html">Documentation OData 
4.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="how-to-build-an-odata-service-with-olingo-v4">How to build an 
OData Service with Olingo V4</h1>
+<h1 id="part-3-write-operations">Part 3: Write operations</h1>
+<h2 id="introduction">Introduction</h2>
+<p>This tutorial guides you through the steps required to write an OData 
Service based on the Olingo OData 4.0 Library for Java (based on current 
<em>Olingo 4.0.0-beta-03</em> release which can be get via the <a 
href="/doc/odata4/download.html">Download-Page</a>).</p>
+<p>In the first two tutorials (<a 
href="/doc/odata4/tutorials/read/tutorial_read.html">Read Collection</a> and <a 
href="/doc/odata4/tutorials/readep/tutorial_readep.html">Read Entity</a>), 
we’ve learned how to build a simple OData service that supports read 
operations for collection, single entity and property.</p>
+<p>In the present tutorial, will cover the write operations, which means 
creating an entity, modifying an existing entity and deleting an existing 
entity.</p>
+<p>Note:<br />
+The full implementation of the OData service as described in the present 
tutorial can be found in the <a 
href="/doc/odata4/tutorials/write/sample/DemoService_Tutorial_Write.zip">attached
 zip file</a> (<a 
href="/doc/odata4/tutorials/write/sample/DemoService_Tutorial_Write.zip.md5">md5</a>,
 <a 
href="/doc/odata4/tutorials/write/sample/DemoService_Tutorial_Write.zip.sha512">sha512</a>,
 <a 
href="/doc/odata4/tutorials/write/sample/DemoService_Tutorial_Write.zip.asc">pgp</a>)
 that contains an Eclipse project that can be imported into your Eclipse 
workspace.</p>
+<p>Disclaimer:
+Again, in the present tutorial, 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>
+<hr />
+<h1 id="1-prerequisites">1. Prerequisites</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>
+<hr />
+<h1 id="2-preparation">2. Preparation</h1>
+<p>Follow <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> or as shortcut import the project attached to 
<em>Tutorial Part 2</em> into your Eclipse workspace.</p>
+<p>Afterwards do a <em>Deploy and run</em>: it should be working.</p>
+<hr />
+<h1 id="3-implementation">3. Implementation</h1>
+<p>In our sample scenario, we want to create a product, to be added to the 
list of available products that we maintain in our database-mock.
+This product that we want to create will have a name and a description that 
the user of our service will specify in his HTTP request.
+The Olingo library takes this user request, serializes the request body and 
invokes the corresponding method of our processor class.</p>
+<p>In the previous tutorial 2, we’ve already implemented the 
<code>EntityProcessor</code> interface and registered our class in the servlet, 
but we have not written the implementation for the callback methods that are 
responsible for the write operations.
+This is what we are going to do in the below sections.</p>
+<h2 id="31-implement-the-createentity-method">3.1. Implement the 
createEntity(...) method</h2>
+<p>Open the class 
<code>myservice.mynamespace.service.DemoEntityProcessor</code><br />
+Go to the method <code>createEntity(...)</code><br />
+The method body should be empty, otherwise delete any content.</p>
+<p><strong>Now, how to implement the method?</strong><br />
+Basically, we have to do the same that we did in the 
<code>readEntity(...)</code> method, but the other way ‘round.<br />
+In the <code>createEntity(...)</code> method, we have to retrieve the payload 
from the request and then write it to our mock-database.<br />
+Furthermore, we have to return the created entity in the response payload.</p>
+<p>Again, we can divide our work into 4 steps:</p>
+<ol>
+<li>Analyze the URI</li>
+<li>Handle data in backend</li>
+<li>Serialize</li>
+<li>Configure the response</li>
+</ol>
+<p><strong>In detail</strong></p>
+<p>We have to keep in mind that -for creation - the URL that is executed in 
our example is the following:</p>
+<div class="codehilite"><pre><span class="n">http</span><span 
class="p">:</span><span class="o">//</span><span 
class="n">localhost</span><span class="p">:</span>8080<span 
class="o">/</span><span class="n">DemoService</span><span 
class="o">/</span><span class="n">DemoService</span><span 
class="p">.</span><span class="n">svc</span><span class="o">/</span><span 
class="n">Products</span>
+</pre></div>
+
+
+<p>It is executed as POST request and contains a request body which looks as 
follows:</p>
+<div class="codehilite"><pre><span class="p">{</span>
+  <span class="nt">&quot;ID&quot;</span><span class="p">:</span><span 
class="mi">4</span><span class="p">,</span>
+  <span class="nt">&quot;Name&quot;</span><span class="p">:</span><span 
class="s2">&quot;Gamer Mouse&quot;</span><span class="p">,</span>
+  <span class="nt">&quot;Description&quot;</span><span class="p">:</span><span 
class="s2">&quot;optical mouse - gamer edition&quot;</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p><strong>Steps</strong></p>
+<ol>
+<li>In the implementation, we have to first retrieve the 
<code>EntityCollection</code> and <code>EntityType</code> metadata from the 
<code>UriInfo</code> object.</li>
+<li>The next step is to create the data in our backend.<br />
+  For this purpose, we have to retrieve the data from the HTTP request 
payload.<br />
+  We get the payload from the <code>ODataRequest</code> instance as 
<code>InputStream</code>, which can then be deserialized.
+  Our <code>Storage</code> class is responsible for creating the new product 
in the backend.
+  And for returning the newly created instance.<br />
+  The reason is that our OData service has to return the newly created entity 
in the response body.  </li>
+<li>From now on the procedure is the same like in the 
<code>readEntity(...)</code> method</li>
+<li>The only difference is the status code, that has to be set to <strong>201 
- created</strong> in case of success</li>
+</ol>
+<p>Please find below the sample code for the <em>createEntity()</em> method</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span 
class="kt">void</span> <span class="nf">createEntity</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">requestFormat</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">DeserializerException</span><span class="o">,</span> <span 
class="n">SerializerException</span> <span class="o">{</span>
+
+  <span class="c1">// 1. Retrieve the entity type from the URI</span>
+  <span class="n">EdmEntitySet</span> <span class="n">edmEntitySet</span> 
<span class="o">=</span> <span class="n">Util</span><span 
class="o">.</span><span class="na">getEdmEntitySet</span><span 
class="o">(</span><span class="n">uriInfo</span><span class="o">);</span>
+  <span class="n">EdmEntityType</span> <span class="n">edmEntityType</span> 
<span class="o">=</span> <span class="n">edmEntitySet</span><span 
class="o">.</span><span class="na">getEntityType</span><span 
class="o">();</span>
+
+  <span class="c1">// 2. create the data in backend</span>
+  <span class="c1">// 2.1. retrieve the payload from the POST request for the 
entity to create and deserialize it</span>
+  <span class="n">InputStream</span> <span class="n">requestInputStream</span> 
<span class="o">=</span> <span class="n">request</span><span 
class="o">.</span><span class="na">getBody</span><span class="o">();</span>
+  <span class="n">ODataFormat</span> <span class="n">requestODataFormat</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">requestFormat</span><span class="o">);</span>
+  <span class="n">ODataDeserializer</span> <span class="n">deserializer</span> 
<span class="o">=</span> <span class="k">this</span><span 
class="o">.</span><span class="na">odata</span><span class="o">.</span><span 
class="na">createDeserializer</span><span class="o">(</span><span 
class="n">requestODataFormat</span><span class="o">);</span>
+  <span class="n">DeserializerResult</span> <span class="n">result</span> 
<span class="o">=</span> <span class="n">deserializer</span><span 
class="o">.</span><span class="na">entity</span><span class="o">(</span><span 
class="n">requestInputStream</span><span class="o">,</span> <span 
class="n">edmEntityType</span><span class="o">);</span>
+  <span class="n">Entity</span> <span class="n">requestEntity</span> <span 
class="o">=</span> <span class="n">result</span><span class="o">.</span><span 
class="na">getEntity</span><span class="o">();</span>
+  <span class="c1">// 2.2 do the creation in backend, which returns the newly 
created entity</span>
+  <span class="n">Entity</span> <span class="n">createdEntity</span> <span 
class="o">=</span> <span class="n">storage</span><span class="o">.</span><span 
class="na">createEntityData</span><span class="o">(</span><span 
class="n">edmEntitySet</span><span class="o">,</span> <span 
class="n">requestEntity</span><span class="o">);</span>
+
+  <span class="c1">// 3. serialize the response (we have to return the created 
entity)</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">edmEntitySet</span><span class="o">).</span><span 
class="na">build</span><span class="o">();</span>
+    <span class="c1">// expand and select currently not supported</span>
+  <span class="n">EntitySerializerOptions</span> <span 
class="n">options</span> <span class="o">=</span> <span 
class="n">EntitySerializerOptions</span><span class="o">.</span><span 
class="na">with</span><span class="o">().</span><span 
class="na">contextURL</span><span class="o">(</span><span 
class="n">contextUrl</span><span class="o">).</span><span 
class="na">build</span><span class="o">();</span>
+
+  <span class="n">ODataFormat</span> <span class="n">oDataFormat</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">ODataSerializer</span> <span class="n">serializer</span> 
<span class="o">=</span> <span class="k">this</span><span 
class="o">.</span><span class="na">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="n">SerializerResult</span> <span 
class="n">serializedResponse</span> <span class="o">=</span> <span 
class="n">serializer</span><span class="o">.</span><span 
class="na">entity</span><span class="o">(</span><span 
class="n">serviceMetadata</span><span class="o">,</span> <span 
class="n">edmEntityType</span><span class="o">,</span> <span 
class="n">createdEntity</span><span class="o">,</span> <span 
class="n">options</span><span class="o">);</span>
+
+  <span class="c1">//4. configure the response object</span>
+  <span class="n">response</span><span class="o">.</span><span 
class="na">setContent</span><span class="o">(</span><span 
class="n">serializedResponse</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">CREATED</span><span class="o">.</span><span 
class="na">getStatusCode</span><span class="o">());</span>
+  <span class="n">response</span><span class="o">.</span><span 
class="na">setHeader</span><span class="o">(</span><span 
class="n">HttpHeader</span><span class="o">.</span><span 
class="na">CONTENT_TYPE</span><span class="o">,</span> <span 
class="n">responseFormat</span><span class="o">.</span><span 
class="na">toContentTypeString</span><span class="o">());</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="32-implement-the-updateentity-method">3.2. Implement the 
updateEntity(...) method</h2>
+<p>Example URL</p>
+<div class="codehilite"><pre><span class="n">http</span><span 
class="p">:</span><span class="o">//</span><span 
class="n">localhost</span><span class="p">:</span>8080<span 
class="o">/</span><span class="n">DemoService</span><span 
class="o">/</span><span class="n">DemoService</span><span 
class="p">.</span><span class="n">svc</span><span class="o">/</span><span 
class="n">Products</span><span class="p">(</span>3<span class="p">)</span>
+</pre></div>
+
+
+<p>Example request body:</p>
+<div class="codehilite"><pre><span class="p">{</span>
+  <span class="nt">&quot;ID&quot;</span><span class="p">:</span><span 
class="mi">3</span><span class="p">,</span>
+  <span class="nt">&quot;Name&quot;</span><span class="p">:</span><span 
class="s2">&quot;Ergo Screen updated Name&quot;</span><span class="p">,</span>
+  <span class="nt">&quot;Description&quot;</span><span class="p">:</span><span 
class="s2">&quot;updated description&quot;</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>The <code>updateEntity(...)</code> method is similar.<br />
+Again, we have to retrieve the payload from the HTTP request and use it for 
modifying the data in backend.
+The difference is that case of update operation, the OData service is not 
expected to return any response payload. So we can skip the serialize-step and 
simply set the HTTP status code to <strong>204 – no content</strong></p>
+<div class="codehilite"><pre><span class="kd">public</span> <span 
class="kt">void</span> <span class="nf">updateEntity</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">requestFormat</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">DeserializerException</span><span class="o">,</span> <span 
class="n">SerializerException</span> <span class="o">{</span>
+
+  <span class="c1">// 1. Retrieve the entity set which belongs to the 
requested entity</span>
+  <span class="n">List</span><span class="o">&lt;</span><span 
class="n">UriResource</span><span class="o">&gt;</span> <span 
class="n">resourcePaths</span> <span class="o">=</span> <span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getUriResourceParts</span><span class="o">();</span>
+  <span class="c1">// Note: only in our example we can assume that the first 
segment is the EntitySet</span>
+  <span class="n">UriResourceEntitySet</span> <span 
class="n">uriResourceEntitySet</span> <span class="o">=</span> <span 
class="o">(</span><span class="n">UriResourceEntitySet</span><span 
class="o">)</span> <span class="n">resourcePaths</span><span 
class="o">.</span><span class="na">get</span><span class="o">(</span><span 
class="mi">0</span><span class="o">);</span>
+  <span class="n">EdmEntitySet</span> <span class="n">edmEntitySet</span> 
<span class="o">=</span> <span class="n">uriResourceEntitySet</span><span 
class="o">.</span><span class="na">getEntitySet</span><span class="o">();</span>
+  <span class="n">EdmEntityType</span> <span class="n">edmEntityType</span> 
<span class="o">=</span> <span class="n">edmEntitySet</span><span 
class="o">.</span><span class="na">getEntityType</span><span 
class="o">();</span>
+
+  <span class="c1">// 2. update the data in backend</span>
+  <span class="c1">// 2.1. retrieve the payload from the PUT request for the 
entity to be updated</span>
+  <span class="n">InputStream</span> <span class="n">requestInputStream</span> 
<span class="o">=</span> <span class="n">request</span><span 
class="o">.</span><span class="na">getBody</span><span class="o">();</span>
+  <span class="n">ODataFormat</span> <span class="n">requestODataFormat</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">requestFormat</span><span class="o">);</span>
+  <span class="n">ODataDeserializer</span> <span class="n">deserializer</span> 
<span class="o">=</span> <span class="k">this</span><span 
class="o">.</span><span class="na">odata</span><span class="o">.</span><span 
class="na">createDeserializer</span><span class="o">(</span><span 
class="n">requestODataFormat</span><span class="o">);</span>
+  <span class="n">DeserializerResult</span> <span class="n">result</span> 
<span class="o">=</span> <span class="n">deserializer</span><span 
class="o">.</span><span class="na">entity</span><span class="o">(</span><span 
class="n">requestInputStream</span><span class="o">,</span> <span 
class="n">edmEntityType</span><span class="o">);</span>
+  <span class="n">Entity</span> <span class="n">requestEntity</span> <span 
class="o">=</span> <span class="n">result</span><span class="o">.</span><span 
class="na">getEntity</span><span class="o">();</span>
+  <span class="c1">// 2.2 do the modification in backend</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="c1">// Note that this updateEntity()-method is invoked for both 
PUT or PATCH operations</span>
+  <span class="n">HttpMethod</span> <span class="n">httpMethod</span> <span 
class="o">=</span> <span class="n">request</span><span class="o">.</span><span 
class="na">getMethod</span><span class="o">();</span>
+  <span class="n">storage</span><span class="o">.</span><span 
class="na">updateEntityData</span><span class="o">(</span><span 
class="n">edmEntitySet</span><span class="o">,</span> <span 
class="n">keyPredicates</span><span class="o">,</span> <span 
class="n">requestEntity</span><span class="o">,</span> <span 
class="n">httpMethod</span><span class="o">);</span>
+
+  <span class="c1">//3. configure the response object</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">NO_CONTENT</span><span class="o">.</span><span 
class="na">getStatusCode</span><span class="o">());</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>In case of update, we have to consider the following:<br />
+The update of an entity can be realized in 2 ways: either a 
<strong>PATCH</strong> or a <strong>PUT</strong> request.<br />
+(See the online specification in section <a 
href="http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html";>11.4.3
 Update an Entity</a> for more details.
+For both HTTP methods, our <code>updateEntity(...)</code> will be invoked.<br 
/>
+But we have to treat the data-modification differently.<br />
+Therefore, we have to first retrieve the used HTTP method and in the 
backend-logic, we have to distinguish between <strong>PATCH</strong> and 
<strong>PUT</strong>.<br />
+The difference becomes relevant only in case if the user doesn’t send all 
the properties in the request body.  </p>
+<p>Example: if we modify the above example request body to look as follows:  
</p>
+<div class="codehilite"><pre><span class="p">{</span>
+  <span class="nt">&quot;Description&quot;</span><span class="p">:</span><span 
class="s2">&quot;updated description&quot;</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Note that in this case, only one of three properties is sent in the request 
body.</p>
+<ul>
+<li>If the HTTP method is <strong>PATCH</strong>:<br />
+    The value of the <em>Description</em> property is updated in the 
backend.<br />
+    The values of the other properties remain untouched.</li>
+<li>If the HTTP method is <strong>PUT</strong>:<br />
+    The value of the <em>Description</em> property is updated in the 
backend.<br />
+    The value of the other properties is set to null (exception: key 
properties can never be null).  </li>
+</ul>
+<p>So let’s have a look at our sample implementation in the 
<code>Storage</code> class (see below for full sample code and also see the 
attached zip file containing the whole sample project)</p>
+<div class="codehilite"><pre><span class="kd">private</span> <span 
class="kt">void</span> <span class="nf">updateProduct</span><span 
class="o">(</span><span class="n">EdmEntityType</span> <span 
class="n">edmEntityType</span><span class="o">,</span> <span 
class="n">List</span><span class="o">&lt;</span><span 
class="n">UriParameter</span><span class="o">&gt;</span> <span 
class="n">keyParams</span><span class="o">,</span> <span 
class="n">Entity</span> <span class="n">entity</span><span class="o">,</span> 
<span class="n">HttpMethod</span> <span class="n">httpMethod</span><span 
class="o">)</span>
+                            <span class="kd">throws</span> <span 
class="n">ODataApplicationException</span><span class="o">{</span>
+
+  <span class="n">Entity</span> <span class="n">productEntity</span> <span 
class="o">=</span> <span class="n">getProduct</span><span 
class="o">(</span><span class="n">edmEntityType</span><span class="o">,</span> 
<span class="n">keyParams</span><span class="o">);</span>
+  <span class="k">if</span><span class="o">(</span><span 
class="n">productEntity</span> <span class="o">==</span> <span 
class="kc">null</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">ENGLISH</span><span class="o">);</span>
+  <span class="o">}</span>
+
+  <span class="c1">// loop over all properties and replace the values with the 
values of the given payload</span>
+  <span class="c1">// Note: ignoring ComplexType, as we don&#39;t have it in 
our odata model</span>
+  <span class="n">List</span><span class="o">&lt;</span><span 
class="n">Property</span><span class="o">&gt;</span> <span 
class="n">existingProperties</span> <span class="o">=</span> <span 
class="n">productEntity</span><span class="o">.</span><span 
class="na">getProperties</span><span class="o">();</span>
+  <span class="k">for</span><span class="o">(</span><span 
class="n">Property</span> <span class="n">existingProp</span> <span 
class="o">:</span> <span class="n">existingProperties</span><span 
class="o">){</span>
+    <span class="n">String</span> <span class="n">propName</span> <span 
class="o">=</span> <span class="n">existingProp</span><span 
class="o">.</span><span class="na">getName</span><span class="o">();</span>
+
+    <span class="c1">// ignore the key properties, they aren&#39;t 
updateable</span>
+    <span class="k">if</span><span class="o">(</span><span 
class="n">isKey</span><span class="o">(</span><span 
class="n">edmEntityType</span><span class="o">,</span> <span 
class="n">propName</span><span class="o">)){</span>
+      <span class="k">continue</span><span class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="n">Property</span> <span class="n">updateProperty</span> 
<span class="o">=</span> <span class="n">entity</span><span 
class="o">.</span><span class="na">getProperty</span><span 
class="o">(</span><span class="n">propName</span><span class="o">);</span>
+    <span class="c1">// the request payload might not consider ALL properties, 
so it can be null</span>
+    <span class="k">if</span><span class="o">(</span><span 
class="n">updateProperty</span> <span class="o">==</span> <span 
class="kc">null</span><span class="o">){</span>
+      <span class="c1">// if a property has NOT been added to the request 
payload</span>
+      <span class="c1">// depending on the HttpMethod, our behavior is 
different</span>
+      <span class="k">if</span><span class="o">(</span><span 
class="n">httpMethod</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">HttpMethod</span><span class="o">.</span><span 
class="na">PATCH</span><span class="o">)){</span>
+        <span class="c1">// in case of PATCH, the existing property is not 
touched</span>
+        <span class="k">continue</span><span class="o">;</span> <span 
class="c1">// do nothing</span>
+      <span class="o">}</span><span class="k">else</span> <span 
class="k">if</span><span class="o">(</span><span 
class="n">httpMethod</span><span class="o">.</span><span 
class="na">equals</span><span class="o">(</span><span 
class="n">HttpMethod</span><span class="o">.</span><span 
class="na">PUT</span><span class="o">)){</span>
+        <span class="c1">// in case of PUT, the existing property is set to 
null</span>
+        <span class="n">existingProp</span><span class="o">.</span><span 
class="na">setValue</span><span class="o">(</span><span 
class="n">existingProp</span><span class="o">.</span><span 
class="na">getValueType</span><span class="o">(),</span> <span 
class="kc">null</span><span class="o">);</span>
+        <span class="k">continue</span><span class="o">;</span>
+      <span class="o">}</span>
+    <span class="o">}</span>
+
+    <span class="c1">// change the value of the properties</span>
+    <span class="n">existingProp</span><span class="o">.</span><span 
class="na">setValue</span><span class="o">(</span><span 
class="n">existingProp</span><span class="o">.</span><span 
class="na">getValueType</span><span class="o">(),</span> <span 
class="n">updateProperty</span><span class="o">.</span><span 
class="na">getValue</span><span class="o">());</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h2 id="33-implement-the-deleteentity-method">3.3. Implement the 
deleteEntity(...) method</h2>
+<p>In case of <strong>DELETE</strong> operation, the URL is the same like for 
the <strong>GET</strong> operation, but the request body is empty.</p>
+<p>Example URL:</p>
+<div class="codehilite"><pre><span class="n">http</span><span 
class="p">:</span><span class="o">//</span><span 
class="n">localhost</span><span class="p">:</span>8080<span 
class="o">/</span><span class="n">DemoService</span><span 
class="o">/</span><span class="n">DemoService</span><span 
class="p">.</span><span class="n">svc</span><span class="o">/</span><span 
class="n">Products</span><span class="p">(</span>3<span class="p">)</span>
+</pre></div>
+
+
+<p>The implementation is rather simple:  </p>
+<ul>
+<li>As usual, determine the entity set.  </li>
+<li>Delete the data in backend.  </li>
+<li>
+<p>Configure the response object with the proper status code <strong>204 – 
no content</strong>.  </p>
+<div class="codehilite"><pre><span class="kd">public</span> <span 
class="kt">void</span> <span class="nf">deleteEntity</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="kd">throws</span> <span 
class="n">ODataApplicationException</span> <span class="o">{</span>
+
+  <span class="c1">// 1. Retrieve the entity set which belongs to the 
requested entity</span>
+  <span class="n">List</span><span class="o">&lt;</span><span 
class="n">UriResource</span><span class="o">&gt;</span> <span 
class="n">resourcePaths</span> <span class="o">=</span> <span 
class="n">uriInfo</span><span class="o">.</span><span 
class="na">getUriResourceParts</span><span class="o">();</span>
+  <span class="c1">// Note: only in our example we can assume that the first 
segment is the EntitySet</span>
+  <span class="n">UriResourceEntitySet</span> <span 
class="n">uriResourceEntitySet</span> <span class="o">=</span> <span 
class="o">(</span><span class="n">UriResourceEntitySet</span><span 
class="o">)</span> <span class="n">resourcePaths</span><span 
class="o">.</span><span class="na">get</span><span class="o">(</span><span 
class="mi">0</span><span class="o">);</span>
+  <span class="n">EdmEntitySet</span> <span class="n">edmEntitySet</span> 
<span class="o">=</span> <span class="n">uriResourceEntitySet</span><span 
class="o">.</span><span class="na">getEntitySet</span><span class="o">();</span>
+
+  <span class="c1">// 2. delete the data in backend</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">storage</span><span class="o">.</span><span 
class="na">deleteEntityData</span><span class="o">(</span><span 
class="n">edmEntitySet</span><span class="o">,</span> <span 
class="n">keyPredicates</span><span class="o">);</span>
+
+  <span class="c1">//3. configure the response object</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">NO_CONTENT</span><span class="o">.</span><span 
class="na">getStatusCode</span><span class="o">());</span>
+<span class="o">}</span>
+</pre></div>
+
+
+</li>
+</ul>
+<h2 id="34-run-the-service">3.4. Run the service</h2>
+<p>After building and deploying the project, we can invoke our OData 
service.</p>
+<p>In order to test the write operations of our OData service, we need a tool 
that is able to execute the following required HTTP requests: 
<strong>POST</strong>, <strong>PUT</strong>, <strong>PATCH</strong>, 
<strong>DELETE</strong><br />
+This is usually done with any REST client tool that can be installed into the 
browser of your choice.  </p>
+<p>Examples:<br />
+    - Firefox: “RESTClient, a debugger for RESTful web services”<br />
+    - Chrome: “Advanced REST client”  </p>
+<p>The following sections provide examples for executing the requests:</p>
+<h3 id="341-example-for-create">3.4.1. Example for 
<strong>CREATE</strong>:</h3>
+<ul>
+<li>URL: <a 
href="http://localhost:8080/DemoService/DemoService.svc/Products";>http://localhost:8080/DemoService/DemoService.svc/Products</a>
  </li>
+<li>HTTP verb: <strong>POST</strong></li>
+<li>Header: <code>Content-Type: application/json; 
odata.metadata=minimal</code>  </li>
+<li>
+<p>Request body:  </p>
+<div class="codehilite"><pre><span class="p">{</span>  
+  <span class="nt">&quot;ID&quot;</span><span class="p">:</span><span 
class="mi">6</span><span class="p">,</span>  
+  <span class="nt">&quot;Name&quot;</span><span class="p">:</span><span 
class="s2">&quot;Gamer Mouse&quot;</span><span class="p">,</span>  
+  <span class="nt">&quot;Description&quot;</span><span class="p">:</span><span 
class="s2">&quot;optical mouse - gamer edition&quot;</span>  
+<span class="p">}</span>
+</pre></div>
+
+
+</li>
+</ul>
+<p>Note:
+The value for the ID property is arbitrary, as it will be generated by our 
OData service implementation</p>
+<h3 id="342-example-for-update-put">3.4.2. Example for UPDATE (PUT):</h3>
+<ul>
+<li>URL: <a 
href="http://localhost:8080/DemoService/DemoService.svc/Products(3)">http://localhost:8080/DemoService/DemoService.svc/Products(3)</a>
  </li>
+<li>HTTP verb: <strong>PUT</strong></li>
+<li>Header: <code>Content-Type: application/json; 
odata.metadata=minimal</code>  </li>
+<li>
+<p>Request body:  </p>
+<div class="codehilite"><pre><span class="p">{</span>  
+  <span class="nt">&quot;ID&quot;</span><span class="p">:</span><span 
class="mi">3</span><span class="p">,</span>  
+  <span class="nt">&quot;Name&quot;</span><span class="p">:</span><span 
class="s2">&quot;Ergo Screen updated Name&quot;</span><span class="p">,</span>  
+  <span class="nt">&quot;Description&quot;</span><span class="p">:</span><span 
class="s2">&quot;updated description&quot;</span>  
+<span class="p">}</span>
+</pre></div>
+
+
+</li>
+</ul>
+<h3 id="343-example-for-update-patch">3.4.3. Example for UPDATE (PATCH):</h3>
+<ul>
+<li>URL: <a 
href="http://localhost:8080/DemoService/DemoService.svc/Products(3)">http://localhost:8080/DemoService/DemoService.svc/Products(3)</a>
  </li>
+<li>HTTP verb: <strong>PATCH</strong>  </li>
+<li>Header: <code>Content-Type: application/json; 
odata.metadata=minimal</code>  </li>
+<li>
+<p>Request body:  </p>
+<div class="codehilite"><pre><span class="p">{</span>  
+  <span class="nt">&quot;Description&quot;</span><span class="p">:</span> 
<span class="s2">&quot;patched description&quot;</span>  
+<span class="p">}</span>
+</pre></div>
+
+
+</li>
+</ul>
+<h3 id="344-example-for-delete">3.4.4. Example for DELETE:</h3>
+<ul>
+<li>URL: <a 
href="http://localhost:8080/DemoService/DemoService.svc/Products(3)">http://localhost:8080/DemoService/DemoService.svc/Products(3)</a>
  </li>
+<li>HTTP verb: <strong>DELETE</strong>  </li>
+<li>Header: Content-Type: application/json; odata.metadata=minimal  </li>
+<li>Request body:  <code>&lt;empty&gt;</code></li>
+</ul>
+<hr />
+<h1 id="4-summary">4. Summary</h1>
+<p>In this tutorial we have learned how to implement the creation, update and 
deletion of an entity.<br />
+It has been based on a simple OData model, focusing on simple sample code and 
sample data.  </p>
+<p>In the next tutorial (Part 4: Navigation) we will learn how to implement 
navigation, i.e. the linking of resources.</p>
+<hr />
+<h1 id="5-links">5. Links</h1>
+<p>Tutorial OData V4 service part 1: <a 
href="/doc/odata4/tutorials/read/tutorial_read.html">Read Entity Collection</a> 
| <a 
href="/doc/odata4/tutorials/read/sample/DemoService_Tutorial_Read.zip">sample 
project zip</a><br />
+Tutorial OData V4 service part 2: <a 
href="/doc/odata4/tutorials/readep/tutorial_readep.html">Read Entity, Read 
Property</a> | <a 
href="/doc/odata4/tutorials/readep/sample/DemoService_Tutorial_Readep.zip">sample
 project zip</a><br />
+Tutorial OData V4 service part 3: <a 
href="/doc/odata4/tutorials/write/tutorial_write.html">Write (Create, Update, 
Delete Entity) - (this page)</a> | <a 
href="/doc/odata4/tutorials/write/sample/DemoService_Tutorial_Write.zip">sample 
project zip</a><br />
+Tutorial OData V4 service, part 4: <a href="...">Navigation - (To Be 
Announced)</a></p>
+<p>OData specification: <a href="http://odata.org/";>http://odata.org/</a>
+Olingo Javadoc: <a 
href="http://olingo.apache.org/javadoc/odata4/index.html";>http://olingo.apache.org/javadoc/odata4/index.html</a></p><div
 align="center">
+<p>Copyright © 2013-2015, The Apache Software Foundation<br>
+                                               Apache Olingo, Olingo, Apache, 
the Apache feather, and
+                               the Apache Olingo project logo are trademarks 
of the Apache Software
+                               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