Author: buildbot
Date: Tue Apr 28 11:33:25 2015
New Revision: 949477
Log:
Staging update by buildbot for olingo
Added:
websites/staging/olingo/trunk/content/doc/odata4/tutorials/read/tutorial_read.html
Removed:
websites/staging/olingo/trunk/content/doc/odata4/tutorials/read/tutorial_read.md
Modified:
websites/staging/olingo/trunk/content/ (props changed)
Propchange: websites/staging/olingo/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Tue Apr 28 11:33:25 2015
@@ -1 +1 @@
-1676487
+1676492
Added:
websites/staging/olingo/trunk/content/doc/odata4/tutorials/read/tutorial_read.html
==============================================================================
---
websites/staging/olingo/trunk/content/doc/odata4/tutorials/read/tutorial_read.html
(added)
+++
websites/staging/olingo/trunk/content/doc/odata4/tutorials/read/tutorial_read.html
Tue Apr 28 11:33:25 2015
@@ -0,0 +1,873 @@
+<!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>
+<p>This tutorial guides you through the steps required to write an OData
Service based on the Olingo OData 4.0 Library for Java.</p>
+<p>We will create a Web Application and deploy it on a local Tomcat server.
+Afterwards, the OData service can be invoked from a browser and it will
provide the data according to the OData V4 specification.
+This tutorial is kept as minimalistic as possible, in order to fully
concentrate on the implementation of the service.
+For example, only READ scenario is covered in this tutorial, whereas creation,
modification and deletion will be covered in the subsequent tutorial.</p>
+<p><strong>Scenario</strong></p>
+<p>The OData service that weâre going to create will implement the following
model:</p>
+<p><img alt="datamodel" src="model1.png" title="The OData model" /></p>
+<p>The service will display a list of products and a few properties that
describe each product.
+This data model will be enhanced in the subsequent tutorials in order to
display Categories and to support navigation from a product to its Category.</p>
+<p><strong>Goal</strong></p>
+<p>We will be dealing with 3 java classes and the web.xml descriptor file.
+Furthermore, for building with maven, weâll edit the pom.xml file.</p>
+<p>This is how our working directory in Eclipse will look like:</p>
+<p><img alt="projectLayout" src="EclipseProjectTree.png" title="The project
layout" /></p>
+<p>At the end of this tutorial, youâll have written an OData service and
youâll be able to invoke the following URL in a browser:</p>
+<p>http://localhost:8080/DemoService/DemoService.svc/Products</p>
+<p>And the browser will display the following little collection of data:
+<img alt="productCollection" src="productCollectionPayload.png" title="The
product collection" /></p>
+<p><code>json
+{"@odata.context":"$metadata#Products","value":[{"ID":1,"Name":"Notebook Basic
15","Description":"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM -
40GB"},{"ID":2,"Name":"1UMTS PDA","Description":"Ultrafast 3G UMTS/HSDPA Pocket
PC, supports GSM network"},{"ID":3,"Name":"Ergo Screen","Description":"17
Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"}]}</code></p>
+<p><strong>Table of Contents</strong></p>
+<ol>
+<li>Prerequisites</li>
+<li>Preparation</li>
+<li>Create Project</li>
+<li>Create Project</li>
+<li>Edit pom file</li>
+<li>Check build path</li>
+<li>Build the project</li>
+<li>Implementation - Read scenario to request the EntitySet âProductsâ</li>
+<li>Declare the metadata</li>
+<li>Provide the data</li>
+<li>Web application implementation</li>
+<li>Run the service</li>
+<li>Run with Eclipse</li>
+<li>The Service URLs</li>
+<li>Summary</li>
+</ol>
+<hr />
+<h1 id="1-prerequisites">1. Prerequisites</h1>
+<p>In order to follow this tutorial, you should have</p>
+<ul>
+<li>Basic knowledge about OData and OData V4</li>
+<li>Knowledge about Java as programming language</li>
+<li>Optional: knowledge about developing web applications</li>
+<li>Optional: knowledge about building with Maven</li>
+</ul>
+<hr />
+<h1 id="2-preparation">2. Preparation</h1>
+<p>Before starting off with the creation of our OData service, we need to
prepare for the following needs:
+1. An IDE for writing the Java code
+2. A builder to build the .war file, which will be deployed on server
+3. A web server to run our web application / OData service</p>
+<p>I recommend using Eclipse for all 3 needs, as it is the easiest approach.
+This means, you should install the pre-packed Eclipse distribution called
âEclipse IDE for Java EE developersâ and which can be found here:
http://www.eclipse.org/downloads/</p>
+<p><img alt="eclipseDownload" src="eclipseDownload.png" title="The Eclipse EE
download" /></p>
+<p>This Eclipse package contains an embedded server and also an integrated
Maven builder.</p>
+<hr />
+<h1 id="3-create-project">3. Create Project</h1>
+<p>The recommended procedure to create a project is to use Maven, because it
offers an archetype for generating the project skeleton.
+Furthermore, using Maven is convenient for managing the build dependencies.
+The description within this section is based on an Eclipse installation that
contains the Maven integration.</p>
+<p><strong>Create Project using the maven archetype âwebappâ</strong></p>
+<p>Within Eclipse, open the Maven Project wizard via
+<em>File -> New -> other -> Maven -> Maven Project</em></p>
+<p>On the second wizard page, choose the archetype: maven-archetype-webapp</p>
+<p><img alt="mavenArchetype" src="mavenArchetype.png" title="The Maven
Archetype" /></p>
+<p>On the next page, enter the following information:
+- Project Name: DemoService
+- Groupd Id: my.group.id
+- Artifact Id: DemoService
+- Version: 0.0.1
+- Package: myservice.mynamespace.service</p>
+<blockquote>
+<p>Note:
+If youâre using this wizard for the first time, it might take some time, as
maven needs to download the archetype itself to your local maven-repo.</p>
+</blockquote>
+<p>After finishing the wizard, the next step is to edit the pom.xml file.</p>
+<p><strong>Edit pom file</strong></p>
+<p>In our project, weâll be using several libraries, e.g. the Olingo
libraries.
+In the pom.xml file, we specify the dependencies and Maven will take care to
download them to our local maven repository.
+Furthermore, the pom.xml file tells Maven which output we want to have as
result of our build. In our case, this is a war file.</p>
+<p>In our example, the pom.xml file looks as follows:</p>
+<p>```xml
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>my.group.id</groupId>
+ <artifactId>DemoService</artifactId>
+ <packaging>war</packaging>
+ <version>0.0.1</version></p>
+<div class="codehilite"><pre><span class="nt"><name></span>DemoService
Maven Webapp<span class="nt"></name></span>
+
+<span class="nt"><properties></span>
+ <span class="nt"><javax</span><span class="err">.version</span><span
class="nt">></span>2.5<span class="nt"></javax.version></span>
+ <span class="nt"><odata</span><span class="err">.version</span><span
class="nt">></span>4.0.0-beta-02<span
class="nt"></odata.version></span>
+ <span class="nt"><slf4j</span><span class="err">.version</span><span
class="nt">></span>1.7.7<span class="nt"></slf4j.version></span>
+<span class="nt"></properties></span>
+
+<span class="nt"><dependencies></span>
+ <span class="nt"><dependency></span>
+ <span class="nt"><groupId></span>javax.servlet<span
class="nt"></groupId></span>
+ <span class="nt"><artifactId></span>servlet-api<span
class="nt"></artifactId></span>
+ <span class="nt"><version></span><span class="cp">${</span><span
class="n">javax</span><span class="o">.</span><span
class="n">version</span><span class="cp">}</span><span
class="nt"></version></span>
+ <span class="nt"><scope></span>provided<span
class="nt"></scope></span>
+ <span class="nt"></dependency></span>
+
+ <span class="nt"><dependency></span>
+ <span class="nt"><groupId></span>org.apache.olingo<span
class="nt"></groupId></span>
+ <span class="nt"><artifactId></span>odata-server-api<span
class="nt"></artifactId></span>
+ <span class="nt"><version></span><span class="cp">${</span><span
class="n">odata</span><span class="o">.</span><span
class="n">version</span><span class="cp">}</span><span
class="nt"></version></span>
+ <span class="nt"></dependency></span>
+ <span class="nt"><dependency></span>
+ <span class="nt"><groupId></span>org.apache.olingo<span
class="nt"></groupId></span>
+ <span class="nt"><artifactId></span>odata-server-core<span
class="nt"></artifactId></span>
+ <span class="nt"><version></span><span class="cp">${</span><span
class="n">odata</span><span class="o">.</span><span
class="n">version</span><span class="cp">}</span><span
class="nt"></version></span>
+ <span class="nt"><scope></span>runtime<span
class="nt"></scope></span>
+ <span class="nt"></dependency></span>
+
+ <span class="nt"><dependency></span>
+ <span class="nt"><groupId></span>org.apache.olingo<span
class="nt"></groupId></span>
+ <span class="nt"><artifactId></span>odata-commons-api<span
class="nt"></artifactId></span>
+ <span class="nt"><version></span><span class="cp">${</span><span
class="n">odata</span><span class="o">.</span><span
class="n">version</span><span class="cp">}</span><span
class="nt"></version></span>
+ <span class="nt"></dependency></span>
+ <span class="nt"><dependency></span>
+ <span class="nt"><groupId></span>org.apache.olingo<span
class="nt"></groupId></span>
+ <span class="nt"><artifactId></span>odata-commons-core<span
class="nt"></artifactId></span>
+ <span class="nt"><version></span><span class="cp">${</span><span
class="n">odata</span><span class="o">.</span><span
class="n">version</span><span class="cp">}</span><span
class="nt"></version></span>
+ <span class="nt"></dependency></span>
+
+ <span class="nt"><dependency></span>
+ <span class="nt"><groupId></span>org.slf4j<span
class="nt"></groupId></span>
+ <span class="nt"><artifactId></span>slf4j-simple<span
class="nt"></artifactId></span>
+ <span class="nt"><version></span><span class="cp">${</span><span
class="n">slf4j</span><span class="o">.</span><span
class="n">version</span><span class="cp">}</span><span
class="nt"></version></span>
+ <span class="nt"><scope></span>runtime<span
class="nt"></scope></span>
+ <span class="nt"></dependency></span>
+<span class="nt"></dependencies></span>
+</pre></div>
+
+
+<p></project>
+```</p>
+<p><strong>Check Java build path</strong></p>
+<p>In order to check the Build path settings, open the context menu on the
project and choose
+<em>Build Path -> Configure Build Pathâ¦</em></p>
+<p><img alt="ConfigureBuildPathAction" src="ConfigureBuildPathAction.png"
title="Open the Configure BuildPath action" /></p>
+<p>Select the <em>Source</em> tab.
+You might see that the source folder <em>src/main/java</em> is configured, but
marked with an error marker.</p>
+<p><img alt="ConfigureBuildPathErr" src="ConfigureBuildPathErr.png"
title="Configure BuildPath has errors" /></p>
+<p>The reason is that it is missing on file system.
+So the solution is to create the required folder in Eclipse.</p>
+<p><img alt="createFolder" src="createFolder.png" title="Create new java
folder" /></p>
+<p>Afterwards, open the Build Path dialog again.
+The second error might be about missing test source folder.
+Since we donât need it for our tutorial, we remove it from the build
path.</p>
+<p><img alt="ConfigureBuildPathOK" src="ConfigureBuildPathOK.png"
title="Configure Build Path is OK now" /></p>
+<p><strong>Build the project</strong></p>
+<p>Although the project doesnât contain any source files yet, letâs
perform our first Maven build, in order to check if there are any problems.</p>
+<p>From context menu on project node, chose <em>Run As -> maven build</em>
+If youâve never executed the build before, Maven asks you to specify at
least one goal.
+Enter the usual goals âclean installâ and press âRunâ</p>
+<p><img alt="mavenBuild" src="mavenBuild.png" title="The Maven build dialog"
/></p>
+<p>The log output is provided in the Eclipse Console view.
+You should check it for the output âBuild Successâ</p>
+<blockquote>
+<p>Note:
+It might be the case that maven provides an error marker right from the
beginning.
+In such case it helps to update your Project:
+From context menu on project node, choose Maven -> update Project ->
<your project></p>
+</blockquote>
+<hr />
+<h1 id="4-implementation">4. Implementation</h1>
+<p>The implementation of an OData service based on Olingo server library can
be grouped in the following steps: </p>
+<ul>
+<li>Declaring the metadata of the service</li>
+<li>Handle service requests </li>
+</ul>
+<p>Furthermore, since our example service has to run on a web server, we have
to create some code which allows to call our service in a web application: </p>
+<ul>
+<li>Web application implementation</li>
+</ul>
+<p>The following section will guide you through every step in detail.</p>
+<h2 id="41-declare-the-metadata">4.1. Declare the metadata</h2>
+<h3 id="411-background">4.1.1. Background</h3>
+<p>According to the OData specification, an OData service has to declare its
structure in the so-called <em>metadata document</em>.
+This document defines the contract, such that the user of the service knows
which requests can be executed, the structure of the result and how the service
can be navigated.</p>
+<p>The metadata document can be invoked via the following URI:</p>
+<p><code>html
+ <serviceroot>/$metadata</code></p>
+<p>Furthermore, OData specifies the usage of the so-called service document
+Here, the user can see which Entity Collections are offered by an OData
service.</p>
+<p>The service document can be invoked via the following URI:</p>
+<p><code>html
+ <serviceroot>/</code></p>
+<p>The information that is given by these 2 URIs, has to be implemented in the
service code.
+Olingo provides API for it and weâll use it in the implementation of our
<em>EdmProvider.</em></p>
+<h3 id="412-create-class">4.1.2. Create class</h3>
+<p>Create package <em>myservice.mynamespace.service</em><br />
+Create class <em>DemoEdmProvider</em> and specify the superclass
<em>org.apache.olingo.server.api.edm.provider.EdmProvider</em></p>
+<p>Note: <strong>edm</strong> is the abbreviation for <strong>Entity Data
Model</strong>.<br />
+Accordingly, we understand that the <em>EdmProvider</em> is supposed to
provide static descriptive information.</p>
+<p>The Entity Model of the service can be defined in the EDM Provider. The EDM
model basically defines the available EntityTypes and the relation between the
entities. An EntityType consists of primitive, complex or navigation
properties. The model can be invoked with the metadata document request.</p>
+<p>As we can see, the Olingo server API provides one package that contains
interfaces for the description of the metadata:</p>
+<p><img alt="edmPackage" src="edmPackage.png" title="The edm package" /></p>
+<p>Some of these interfaces are going to be used in the following sections.
+Note:
+You can find the Javadoc here:
http://olingo.apache.org/javadoc/odata4/index.html</p>
+<h3 id="413-implement-the-required-methods">4.1.3. Implement the required
methods</h3>
+<p>The base class <em>EdmProvider</em> provides methods for declaring the
metadata of all OData elements.</p>
+<p>For example:
+<em> The entries that are displayed in the service document are provided by
the method
+</em>getEntityContainerInfo()<em>
+</em> The structure of EntityTypes is declared in the method
<em>getEntityType()</em></p>
+<p>In our simple example, we implement the minimum amount of methods, required
to run a meaningful OData service.<br />
+These are:</p>
+<ul>
+<li><strong><em>getEntityType()</em></strong><br />
+ Here we declare the EntityType âProductâ and a few of its
properties</li>
+<li><strong><em>getEntitySet()</em></strong><br />
+ Here we state that the list of products can be called via the EntitySet
âProductsâ</li>
+<li><strong><em>getEntityContainer()</em></strong><br />
+ Here we provide a Container element that is necessary to host the
EntitySet.</li>
+<li><strong><em>getSchemas()</em></strong><br />
+ The Schema is the root element to carry the elements.</li>
+<li><strong><em>getEntityContainerInfo()</em></strong>
+ Information about the EntityContainer to be displayed in the Service
Document</li>
+</ul>
+<p>In Eclipse, in order to select the methods to override, right click into
the Java editor and from the context menu choose <em>Source ->
Override/Implement Methodsâ¦</em>
+Select the mentioned methods and press OK.</p>
+<p><img alt="overrideMethods" src="overrideMethods.png" title="The dialog for
overriding superclass methods in Eclipse" /></p>
+<p>Letâs have a closer look at the methods in detail.</p>
+<p>First, we need to declare some constants, to be used in below code</p>
+<p>```java
+// Service Namespace
+public static final String NAMESPACE = "com.example.model";</p>
+<p>// EDM Container
+public static final String CONTAINER_NAME = "Container";
+public static final FullQualifiedName CONTAINER = new
FullQualifiedName(NAMESPACE, CONTAINER_NAME);</p>
+<p>// Entity Types Names
+public static final String ET_PRODUCT_NAME = "Product";
+public static final FullQualifiedName ET_PRODUCT_FQN = new
FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME);</p>
+<p>// Entity Set Names
+public static final String ES_PRODUCTS_NAME = "Products";
+```</p>
+<p><strong><em>getEntityType()</em></strong></p>
+<p>In our example service, we want to provide a list of products to users who
call the OData service.
+The user of our service, for example an app-developer, will ask himself: how
does such a "product" entry look like? How is it structured? Which information
about a product is provided? For example, the name of it? And which data types
can be expected from these properties?<br />
+Such information is provided by the <em>EdmProvider</em>.</p>
+<p>In our example service, for modelling the <em>EntityType</em>, we have to
provide the following metadata:</p>
+<p>The name of the EntityType: âProductâ<br />
+The properties: name and type and additional info, e.g. âIDâ of type
âedm.int32â<br />
+Which of the properties is the âkeyâ property: a reference to the âIDâ
property. </p>
+<p>```java
+@Override
+public EntityType getEntityType(FullQualifiedName entityTypeName) throws
ODataException {</p>
+<div class="codehilite"><pre><span class="c1">// this method is called for one
of the EntityTypes that are configured in the Schema</span>
+<span class="k">if</span><span class="p">(</span><span
class="n">entityTypeName</span><span class="p">.</span><span
class="n">equals</span><span class="p">(</span><span
class="no">ET_PRODUCT_FQN</span><span class="p">)){</span>
+
+ <span class="c1">//create EntityType properties</span>
+ <span class="n">Property</span> <span class="n">id</span> <span
class="o">=</span> <span class="k">new</span> <span
class="n">Property</span><span class="p">().</span><span
class="n">setName</span><span class="p">(</span><span
class="s">"ID"</span><span class="p">).</span><span
class="n">setType</span><span class="p">(</span><span
class="n">EdmPrimitiveTypeKind</span><span class="p">.</span><span
class="n">Int32</span><span class="p">.</span><span
class="n">getFullQualifiedName</span><span class="p">());</span>
+ <span class="n">Property</span> <span class="n">name</span> <span
class="o">=</span> <span class="k">new</span> <span
class="n">Property</span><span class="p">().</span><span
class="n">setName</span><span class="p">(</span><span
class="s">"Name"</span><span class="p">).</span><span
class="n">setType</span><span class="p">(</span><span
class="n">EdmPrimitiveTypeKind</span><span class="p">.</span><span
class="n">String</span><span class="p">.</span><span
class="n">getFullQualifiedName</span><span class="p">());</span>
+ <span class="n">Property</span> <span class="n">description</span> <span
class="o">=</span> <span class="k">new</span> <span
class="n">Property</span><span class="p">().</span><span
class="n">setName</span><span class="p">(</span><span
class="s">"Description"</span><span class="p">).</span><span
class="n">setType</span><span class="p">(</span><span
class="n">EdmPrimitiveTypeKind</span><span class="p">.</span><span
class="n">String</span><span class="p">.</span><span
class="n">getFullQualifiedName</span><span class="p">());</span>
+
+ <span class="c1">// create PropertyRef for Key element</span>
+ <span class="n">PropertyRef</span> <span class="n">propertyRef</span>
<span class="o">=</span> <span class="k">new</span> <span
class="n">PropertyRef</span><span class="p">();</span>
+ <span class="n">propertyRef</span><span class="p">.</span><span
class="n">setPropertyName</span><span class="p">(</span><span
class="s">"ID"</span><span class="p">);</span>
+
+ <span class="c1">// configure EntityType</span>
+ <span class="n">EntityType</span> <span class="n">entityType</span> <span
class="o">=</span> <span class="k">new</span> <span
class="n">EntityType</span><span class="p">();</span>
+ <span class="n">entityType</span><span class="p">.</span><span
class="n">setName</span><span class="p">(</span><span
class="no">ET_PRODUCT_NAME</span><span class="p">);</span>
+ <span class="n">entityType</span><span class="p">.</span><span
class="n">setProperties</span><span class="p">(</span><span
class="n">Arrays</span><span class="p">.</span><span
class="n">asList</span><span class="p">(</span><span class="n">id</span><span
class="p">,</span> <span class="n">name</span> <span class="p">,</span> <span
class="n">description</span><span class="p">));</span>
+ <span class="n">entityType</span><span class="p">.</span><span
class="n">setKey</span><span class="p">(</span><span
class="n">Arrays</span><span class="p">.</span><span
class="n">asList</span><span class="p">(</span><span
class="n">propertyRef</span><span class="p">));</span>
+
+ <span class="k">return</span> <span class="n">entityType</span><span
class="p">;</span>
+<span class="p">}</span>
+
+<span class="k">return</span> <span class="k">null</span><span
class="p">;</span>
+</pre></div>
+
+
+<p>}
+```</p>
+<p><strong><em>getEntitySet()</em></strong></p>
+<p>The procedure for declaring the <em>EntitySets</em> is similar.
+An <em>EntitySet</em> is a crucial resource, when an OData service is used to
request data.
+In our example, weâll invoke the following URL, which we expect to provide
us a list of products:
+<code>html
+http://localhost:8080/DemoService/DemoServlet.svc/Products</code>
+When declaring an <em>EntitySet</em>, we need to define the type of entries
which are contained in the list. Such type is an <em>EntityType</em>.
+In our example, we set our previously created <em>EntityType</em>, which is
referred by a <em>FullQualifiedName</em>.</p>
+<p>```java
+@Override
+public EntitySet getEntitySet(FullQualifiedName entityContainer, String
entitySetName) throws ODataException {</p>
+<div class="codehilite"><pre><span class="k">if</span><span
class="p">(</span><span class="n">entityContainer</span><span
class="p">.</span><span class="n">equals</span><span class="p">(</span><span
class="n">CONTAINER</span><span class="p">)){</span>
+ <span class="k">if</span><span class="p">(</span><span
class="n">entitySetName</span><span class="p">.</span><span
class="n">equals</span><span class="p">(</span><span
class="n">ES_PRODUCTS_NAME</span><span class="p">)){</span>
+ <span class="n">EntitySet</span> <span class="n">entitySet</span>
<span class="p">=</span> <span class="n">new</span> <span
class="n">EntitySet</span><span class="p">();</span>
+ <span class="n">entitySet</span><span class="p">.</span><span
class="n">setName</span><span class="p">(</span><span
class="n">ES_PRODUCTS_NAME</span><span class="p">);</span>
+ <span class="n">entitySet</span><span class="p">.</span><span
class="n">setType</span><span class="p">(</span><span
class="n">ET_PRODUCT_FQN</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">entitySet</span><span
class="p">;</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">return</span> <span class="n">null</span><span
class="p">;</span>
+</pre></div>
+
+
+<p>}
+```</p>
+<p><strong><em>getEntityContainer()</em></strong></p>
+<p>In order to provide data, our OData service needs an
<em>EntityContainer</em> that carries the <em>EntitySets</em>.
+In our example, we have only one <em>EntitySet</em>, so we create one
<em>EntityContainer</em> and set our <em>EntitySet</em>.</p>
+<p>```java
+@Override
+public EntityContainer getEntityContainer() throws ODataException {</p>
+<div class="codehilite"><pre><span class="c1">// create EntitySets</span>
+<span class="n">List</span><span class="o"><</span><span
class="n">EntitySet</span><span class="o">></span> <span
class="n">entitySets</span> <span class="o">=</span> <span class="k">new</span>
<span class="n">ArrayList</span><span class="o"><</span><span
class="n">EntitySet</span><span class="o">></span><span class="p">();</span>
+<span class="n">entitySets</span><span class="p">.</span><span
class="n">add</span><span class="p">(</span><span
class="n">getEntitySet</span><span class="p">(</span><span
class="no">CONTAINER</span><span class="p">,</span> <span
class="no">ES_PRODUCTS_NAME</span><span class="p">));</span>
+
+<span class="c1">// create EntityContainer</span>
+<span class="n">EntityContainer</span> <span class="n">entityContainer</span>
<span class="o">=</span> <span class="k">new</span> <span
class="n">EntityContainer</span><span class="p">();</span>
+<span class="n">entityContainer</span><span class="p">.</span><span
class="n">setName</span><span class="p">(</span><span
class="no">CONTAINER_NAME</span><span class="p">);</span>
+<span class="n">entityContainer</span><span class="p">.</span><span
class="n">setEntitySets</span><span class="p">(</span><span
class="n">entitySets</span><span class="p">);</span>
+
+<span class="k">return</span> <span class="n">entityContainer</span><span
class="p">;</span>
+</pre></div>
+
+
+<p>}
+```</p>
+<p><strong><em>getSchemas()</em></strong></p>
+<p>Up to this point, we have declared the type of our data
(<em>EntityType</em>) and our list (<em>EntitySet</em>), and weâve put it
into a container (<em>EntityContainer</em>).<br />
+Now weâre required to put all these elements into a <em>Schema</em>.<br />
+While the model of an OData service can have several schemas, in most cases
there will probably be only one schema.<br />
+So, in our example, we create a list of schemas, where we add one new
<em>Schema</em> object.<br />
+The schema is configured with a <em>Namespace</em>, which serves to uniquely
identify all elements.<br />
+Then our elements are added to the Schema.</p>
+<p>```java
+@Override
+public List<Schema> getSchemas() throws ODataException {</p>
+<div class="codehilite"><pre><span class="c1">// create Schema</span>
+<span class="n">Schema</span> <span class="n">schema</span> <span
class="o">=</span> <span class="k">new</span> <span
class="n">Schema</span><span class="p">();</span>
+<span class="n">schema</span><span class="p">.</span><span
class="n">setNamespace</span><span class="p">(</span><span
class="no">NAMESPACE</span><span class="p">);</span>
+
+<span class="c1">// add EntityTypes</span>
+<span class="n">List</span><span class="o"><</span><span
class="n">EntityType</span><span class="o">></span> <span
class="n">entityTypes</span> <span class="o">=</span> <span
class="k">new</span> <span class="n">ArrayList</span><span
class="o"><</span><span class="n">EntityType</span><span
class="o">></span><span class="p">();</span>
+<span class="n">entityTypes</span><span class="p">.</span><span
class="n">add</span><span class="p">(</span><span
class="n">getEntityType</span><span class="p">(</span><span
class="no">ET_PRODUCT_FQN</span><span class="p">));</span>
+<span class="n">schema</span><span class="p">.</span><span
class="n">setEntityTypes</span><span class="p">(</span><span
class="n">entityTypes</span><span class="p">);</span>
+
+<span class="c1">// add EntityContainer</span>
+<span class="n">schema</span><span class="p">.</span><span
class="n">setEntityContainer</span><span class="p">(</span><span
class="n">getEntityContainer</span><span class="p">());</span>
+
+<span class="c1">// finally</span>
+<span class="n">List</span><span class="o"><</span><span
class="n">Schema</span><span class="o">></span> <span
class="n">schemas</span> <span class="o">=</span> <span class="k">new</span>
<span class="n">ArrayList</span><span class="o"><</span><span
class="n">Schema</span><span class="o">></span><span class="p">();</span>
+<span class="n">schemas</span><span class="p">.</span><span
class="n">add</span><span class="p">(</span><span class="n">schema</span><span
class="p">);</span>
+
+<span class="k">return</span> <span class="n">schemas</span><span
class="p">;</span>
+</pre></div>
+
+
+<p>}
+```</p>
+<p><strong><em>getEntityContainerInfo()</em></strong></p>
+<p>```java
+@Override
+public EntityContainerInfo getEntityContainerInfo(FullQualifiedName
entityContainerName) throws ODataException {</p>
+<p>// This method is invoked when displaying the service document at e.g.
http://localhost:8080/DemoService/DemoService.svc
+ if(entityContainerName == null || entityContainerName.equals(CONTAINER)){
+ EntityContainerInfo entityContainerInfo = new EntityContainerInfo();
+ entityContainerInfo.setContainerName(CONTAINER);
+ return entityContainerInfo;
+ }</p>
+<div class="codehilite"><pre><span class="k">return</span> <span
class="n">null</span><span class="p">;</span>
+</pre></div>
+
+
+<p>}
+```</p>
+<p><strong>Summary:</strong><br />
+We have created a class that declares the metadata of our OData service.
+We have declared the main elements of an OData service: <em>EntityType</em>,
<em>EntitySet</em>, <em>EntityContainer</em> and <em>Schema</em>.</p>
+<p>At runtime of an OData service, such metadata can be viewed by invoking the
Metadata Document.</p>
+<p>In our example:
+<code>http://localhost:8080/DemoService/DemoService.svc/$metadata</code></p>
+<p><code>xml
+<?xml version='1.0' encoding='UTF-8'?>
+<edmx:Edmx Version="4.0"
xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
+ <edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
Namespace="com.example.model">
+ <EntityType Name="Product">
+ <Key>
+ <PropertyRef Name="ID"/>
+ </Key>
+ <Property Name="ID" Type="Edm.Int32"/>
+ <Property Name="Name" Type="Edm.String"/>
+ <Property Name="Description" Type="Edm.String"/>
+ </EntityType>
+ <EntityContainer Name="Container">
+ <EntitySet Name="Products"
EntityType="com.example.model.Product"/>
+ </EntityContainer>
+ </Schema>
+ </edmx:DataServices>
+</edmx:Edmx></code></p>
+<p>The Service Document can be invoked to view the Entity Sets, like in our
example at
+<code>http://localhost:8080/DemoService/DemoService.svc/</code></p>
+<p><code>json
+{
+ "@odata.context" :
"http://localhost:8080/DemoService/DemoService.svc/$metadata",
+ "value" : [
+ {
+ "name" : "Products",
+ "url" : "Products"
+ } ]
+}</code></p>
+<blockquote>
+<p>Note:<br />
+After implementing the <em>EdmProvider</em>, we can, as an intermediate step,
build/deploy the service and invoke the 2 static pages: service document and
metadata document.<br />
+If desired, you can proceed with implementing the required steps for web
application as described in
+4.3. And run the application as described in chapter 5</p>
+</blockquote>
+<h2 id="42-provide-the-data">4.2. Provide the data</h2>
+<p>After implementing the <em>EdmProvider</em>, the next step is the main task
of an OData service: provide data.<br />
+In our example, we imagine that our OData service is invoked by a user who
wants to see which products are offered by a web shop.<br />
+He invokes a URL and gets a list of products.<br />
+Providing the list of products is the task that we are going to implement in
this chapter.</p>
+<p>The work that we have to do in this chapter can be divided into 4 tasks:
+1. Check the URI<br />
+ We need to identify the requested resource and have to consider Query
Options (if available)
+2. Provide the data<br />
+ Based on the URI info, we have to obtain the data from our data store (can
be e.g. a Database)
+3. Serialize the data<br />
+ The data has to be transformed into the required format
+4. Configure the response<br />
+ Since weâre implementing a âprocessorâ, the last step is to provide
the response object</p>
+<p>These 4 steps will be considered in the implementation of the
<em>readEntityCollection()</em> method.</p>
+<h3 id="421-background">4.2.1. Background</h3>
+<p>In terms of <em>Olingo</em>, while processing a service request, a
Processor instance is invoked that is supposed to understand the (user HTTP-)
request and deliver the desired data.<br />
+<em>Olingo</em> provides API for processing different kind of service
requests:<br />
+Such a service request can ask for a list of entities, or for one entity, or
one property.</p>
+<p>Example:<br />
+In our example, weâve stated in our metadata document that weâll provide a
list of âproductsâ whenever the <em>EntitySet</em> with name âProductsâ
is invoked.<br />
+This means that the user of our OData service will append the
<em>EntitySet</em> name to the root URL of the service and then invoke the full
URL.<br />
+This is http://localhost:8080/ExampleService1/ExampleServlet1.svc/Products
+So, whenever this URL is fired, Olingo will invoke the
<em>EntityCollectionProcessor</em> implementation of our OData service.
+And our <em>EntityCollectionProcessor</em> implementation is expected to
provide a list of products.</p>
+<p>As weâve already mentioned, the metadata document is the contract for
providing data.
+This means that when it comes to provide the actual data, we have to do it
according to the specified metadata.<br />
+For example, the property names have to match, also the types of the
properties, and, if specified, the length of the strings, etc</p>
+<h3 id="422-create-class">4.2.2. Create class</h3>
+<p>Within our package <em>myservice.mynamespace.service</em>, we create a Java
class <em>DemoEntityCollectionProcessor</em> that implements the interface
<em>org.apache.olingo.server.api.processor.EntityCollectionProcessor</em>.</p>
+<p><img alt="createJavaClass" src="createJavaClass.png" title="The Eclipse
dialog for creating a Java class" /></p>
+<h3 id="423-implement-the-required-methods">4.2.3. Implement the required
methods</h3>
+<p>After creation of the Java class, we can see that there are 2 methods to be
implemented:
+<em> <em>init()</em><br />
+ This method is invoked by the <em>Olingo</em> Framework, allowing us to
store the context object</em> <em>readEntityCollection()</em><br />
+ Here we have to fetch the required data and pass it back to the
<em>Olingo</em> FWK</p>
+<p>Letâs have a closer look</p>
+<p><strong><em>init()</em></strong></p>
+<p>This method is common to all processor interfaces.<br />
+The <em>Olingo</em> framework initializes the processor with an instance of
the <em>OData</em> object.
+According to the Javadoc, this object is the âRoot object for serving
factory tasksâ¦â
+Weâll need it later, so we store it as member variable.</p>
+<p><code>java
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+ }</code></p>
+<p>Donât forget to declare the member variable</p>
+<p><code>java
+ private OData odata;</code></p>
+<p><strong><em>readEntityCollection()</em></strong></p>
+<p>The <em>EntityCollectionProcessor</em> exposes only one method:<br />
+<em>readEntityCollection()</em><br />
+Here we have to understand that this <em>readEntityCollection</em>-method is
invoked, when the OData service is called with an HTTP GET operation for an
entity collection.</p>
+<p>The <em>readEntityCollection</em> method is used to âreadâ the data in
the backend (this can be e.g. a database) and to deliver it to the user who
calls the OData service.</p>
+<p>The method signature:</p>
+<p>The ârequestâ parameter contains raw HTTP information. It is typically
used for creation scenario, where a request body is sent along with the
request.</p>
+<p>With the second parameter, the âresponseâ object is passed to our
method in order to carry the response data. So here we have to set the response
body, along with status code and content-type header.</p>
+<p>The third parameter, the âuriInfoâ, contains information about the
relevant part of the URL. This means, the segments starting after the service
name.<br />
+Example:
+If the user calls the following URL:<br />
+http://localhost:8080/DemoService/DemoService.svc/Products<br />
+The <em>readEntityCollection</em> method is invoked and the <em>uriInfo</em>
object contains one segment: âProductsâ<br />
+If the user calls the following URL:<br />
+http://localhost:8080/DemoService/DemoService.svc/Products?$filter=ID eq 1<br
/>
+Then the <em>readEntityCollection</em> method is invoked and the
<em>uriInfo</em> contains the information about the entity set and furthermore
the system query option $filter and its value.</p>
+<p>The last parameter, the âresponseFormatâ, contains information about
the content type that is requested by the user.<br />
+This means that the user has the choice to receive the data either in XML or
in JSON.<br />
+Example:<br />
+If the user calls the following URL:<br />
+http://localhost:8080/DemoService/DemoService.svc/Products?$format=application/json;odata.metadata=minimal<br
/>
+then the content type is:<br />
+application/json;odata.metadata=minimal<br />
+which means that the payload is formatted in JSON (like it is shown in the
introduction section of this tutorial)</p>
+<blockquote>
+<p>Note:
+The content type can as well be specified via the following request header<br
/>
+Accept: application/json;odata.metadata=minimal<br />
+In this case as well, our readEntityCollection() method will be called with
the parameter responseFormat containing the content type > information.</p>
+<p>Note:
+If the user doesnât specify any content type, then the default is JSON.</p>
+</blockquote>
+<p>Why is this parameter needed?<br />
+Because the <em>readEntityCollection</em> method is supposed to deliver the
data in the format that is requested by the user. Weâll use this parameter
when creating a serializer based on it.</p>
+<p>The steps for implementating the method <em>readEntityCollection</em>
are:</p>
+<ol>
+<li>
+<p>Which data is requested?<br />
+Usually, an OData service provides different <em>EntitySets</em>, so first it
is required to identify which <em>EntitySet</em> has been requested. This
information can be retrieved from the <em>uriInfo</em> object</p>
+</li>
+<li>
+<p>Fetch the data<br />
+As a developer of the OData service, you have to know how and where the data
is stored. In many cases, this would be a database. At this point, you would
connect to your database and fetch the requested data with an appropriate SQL
statement. The data that is fetched from the data storage has to be put into an
<em>EntitySet</em> object.
+Note that this object has to be of type <em>EntitySet</em>, not
<em>EdmEntitySet</em><br />
+The package <em>org.apache.olingo.commons.api.data</em> provides interfaces
that describe the actual data, not the metadata.</p>
+</li>
+</ol>
+<p><img alt="datapackage" src="datapackage.png" title="The package containing
the interfaces for handling runtime data" /></p>
+<ol>
+<li>
+<p>Transform the data<br />
+<em>Olingo</em> expects from us to provide the data as low-level
<em>InputStream</em> object. However, <em>Olingo</em> supports us in doing so,
by providing us with a proper "serializer".
+So what we have to do is create the serializer based on the requested content
type, configure it and call it.</p>
+</li>
+<li>
+<p>Configure the response<br />
+The response object has been passed to us in the method signature. We use it
to set the serialized data (the <em>InputStream</em> object).<br />
+Furthermore, we have to set the HTTP status code, which means that we have the
opportunity to do proper error handling.<br />
+And finally we have to set the content type.</p>
+</li>
+</ol>
+<p>```java
+public void readEntityCollection(ODataRequest request, ODataResponse response,
UriInfo uriInfo, ContentType responseFormat)
+ throws ODataApplicationException, SerializerException
{</p>
+<div class="codehilite"><pre><span class="c1">// 1st retrieve the requested
EntitySet from the uriInfo (representation of the parsed URI)</span>
+<span class="n">List</span><span class="o"><</span><span
class="n">UriResource</span><span class="o">></span> <span
class="n">resourcePaths</span> <span class="o">=</span> <span
class="n">uriInfo</span><span class="p">.</span><span
class="n">getUriResourceParts</span><span class="p">();</span>
+<span class="c1">// in our example, the first segment is the EntitySet:</span>
+<span class="n">UriResourceEntitySet</span> <span
class="n">uriResourceEntitySet</span> <span class="o">=</span> <span
class="p">(</span><span class="n">UriResourceEntitySet</span><span
class="p">)</span> <span class="n">resourcePaths</span><span
class="p">.</span><span class="n">get</span><span class="p">(</span><span
class="mh">0</span><span class="p">);</span>
+<span class="n">EdmEntitySet</span> <span class="n">edmEntitySet</span> <span
class="o">=</span> <span class="n">uriResourceEntitySet</span><span
class="p">.</span><span class="n">getEntitySet</span><span class="p">();</span>
+
+<span class="c1">// 2nd: fetch the data from backend for this requested
EntitySetName and delivere as EntitySet</span>
+<span class="n">EntitySet</span> <span class="n">entitySet</span> <span
class="o">=</span> <span class="n">getData</span><span class="p">(</span><span
class="n">edmEntitySet</span><span class="p">);</span>
+
+<span class="c1">// 3rd: create a serializer based on the requested format
(json)</span>
+<span class="n">ODataFormat</span> <span class="n">format</span> <span
class="o">=</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">ODataSerializer</span> <span class="n">serializer</span> <span
class="o">=</span> <span class="n">odata</span><span class="p">.</span><span
class="n">createSerializer</span><span class="p">(</span><span
class="n">format</span><span class="p">);</span>
+
+<span class="c1">// and serialize the content: transform from the EntitySet
object to InputStream</span>
+<span class="n">EdmEntityType</span> <span class="n">edmEntityType</span>
<span class="o">=</span> <span class="n">edmEntitySet</span><span
class="p">.</span><span class="n">getEntityType</span><span class="p">();</span>
+<span class="n">ContextURL</span> <span class="n">contextUrl</span> <span
class="o">=</span> <span class="n">ContextURL</span><span
class="p">.</span><span class="k">with</span><span class="p">().</span><span
class="n">entitySet</span><span class="p">(</span><span
class="n">edmEntitySet</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="o">=</span>
+ <span class="n">EntityCollectionSerializerOptions</span><span
class="p">.</span><span class="k">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">InputStream</span> <span class="n">serializedContent</span>
<span class="o">=</span> <span class="n">serializer</span><span
class="p">.</span><span class="n">entityCollection</span><span
class="p">(</span><span class="n">edmEntityType</span><span class="p">,</span>
<span class="n">entitySet</span><span class="p">,</span> <span
class="n">opts</span><span class="p">);</span>
+
+<span class="c1">// 4th: configure the response object: set the body, headers
and status code</span>
+<span class="n">response</span><span class="p">.</span><span
class="n">setContent</span><span class="p">(</span><span
class="n">serializedContent</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="no">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="no">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>
+</pre></div>
+
+
+<p>}
+```</p>
+<p><strong><em>getData()</em></strong></p>
+<p>Up to now, we havenât elaborated on fetching the actual data.
+In our tutorial, to keep the code as simple as possible, we use a little
helper method that delivers some hardcoded entries.<br />
+Since weâre supposed to deliver the data inside an <em>EntitySet</em>
instance, we create the instance, ask it for the (initially empty) list of
entities and add some new entities to it.<br />
+We create the entities and their properties according to what we declared in
our <em>ExampleEdmProvider</em> class. So we have to take care to provide the
correct names to the new property objects.</p>
+<p>```java
+private EntitySet getData(EdmEntitySet edmEntitySet){</p>
+<div class="codehilite"><pre><span class="n">EntitySet</span> <span
class="n">entitySet</span> <span class="p">=</span> <span class="n">new</span>
<span class="n">EntitySetImpl</span><span class="p">();</span>
+<span class="n">List</span><span class="o"><</span><span
class="n">Entity</span><span class="o">></span> <span
class="n">entityList</span> <span class="p">=</span> <span
class="n">entitySet</span><span class="p">.</span><span
class="n">getEntities</span><span class="p">();</span>
+
+<span class="o">//</span> <span class="n">add</span> <span
class="n">some</span> <span class="n">sample</span> <span
class="n">product</span> <span class="n">entities</span>
+<span class="n">entityList</span><span class="p">.</span><span
class="n">add</span><span class="p">(</span><span class="n">new</span> <span
class="n">EntityImpl</span><span class="p">()</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">ID</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> 1<span class="p">))</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">Name</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> "<span
class="n">Notebook</span> <span class="n">Basic</span> 15"<span
class="p">))</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">Description</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> "<span
class="n">Notebook</span> <span class="n">Basic</span><span class="p">,</span>
1<span class="p">.</span>7<span class="n">GHz</span> <span class="o">-</span>
15 <span class="n">XGA</span> <span class="o">-</span> 1024<span
class="n">MB</span> <span class="n">DDR2</span> <span class="n">SDRAM</span>
<span class="o">-</span> 40<span class="n">GB</span>"<span
class="p">)));</span>
+<span class="n">entityList</span><span class="p">.</span><span
class="n">add</span><span class="p">(</span><span class="n">new</span> <span
class="n">EntityImpl</span><span class="p">()</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">ID</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> 2<span class="p">))</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">Name</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> "1<span
class="n">UMTS</span> <span class="n">PDA</span>"<span class="p">))</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">Description</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> "<span
class="n">Ultrafast</span> 3<span class="n">G</span> <span
class="n">UMTS</span><span class="o">/</span><span class="n">HSDPA</span> <span
class="n">Pocket</span> <span class="n">PC</span><span class="p">,</span> <span
class="n">supports</span> <span class="n">GSM</span> <span
class="n">network</span>"<span class="p">)));</span>
+
+<span class="n">entityList</span><span class="p">.</span><span
class="n">add</span><span class="p">(</span><span class="n">new</span> <span
class="n">EntityImpl</span><span class="p">()</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">ID</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> 3<span class="p">))</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">Name</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> "<span
class="n">Ergo</span> <span class="n">Screen</span>"<span
class="p">))</span>
+ <span class="p">.</span><span class="n">addProperty</span><span
class="p">(</span><span class="n">new</span> <span
class="n">PropertyImpl</span><span class="p">(</span><span
class="n">null</span><span class="p">,</span> "<span
class="n">Description</span>"<span class="p">,</span> <span
class="n">ValueType</span><span class="p">.</span><span
class="n">PRIMITIVE</span><span class="p">,</span> "17 <span
class="n">Optimum</span> <span class="n">Resolution</span> 1024 <span
class="n">x</span> 768 <span class="p">@</span> 85<span
class="n">Hz</span><span class="p">,</span> <span class="n">resolution</span>
1280 <span class="n">x</span> 960"<span class="p">)));</span>
+
+<span class="k">return</span> <span class="n">entitySet</span><span
class="p">;</span>
+</pre></div>
+
+
+<p>}
+```</p>
+<h2 id="43-web-application">4.3. Web Application</h2>
+<p>After declaring the metadata and providing the data, our OData service
implementation is done.<br />
+The last step is to enable our OData service to be called on a web server.<br
/>
+Therefore, weâre wrapping our service by a web application.</p>
+<p>The web application is defined in the web.xml file, where a servlet is
registered.
+The servlet is a standard <em>HttpServlet</em> which dispatches the user
requests to the <em>Olingo</em> framework.</p>
+<p>Letâs quickly do the remaining steps:</p>
+<h3 id="431-create-and-implement-the-servlet">4.3.1. Create and implement the
Servlet</h3>
+<p>Create a new package <em>myservice.mynamespace.web</em>.
+Create Java class with name <em>DemoServlet</em> that inherits from
<em>HttpServlet</em>.</p>
+<p><img alt="createJavaServletClass" src="createJavaServletClass.png"
title="Creating the servlet class" /></p>
+<p>Override the <em>service()</em> method.<br />
+Basically, what weâre doing here is to create an <em>ODataHttpHandler</em>,
which is a class that is provided by <em>Olingo</em>.
+It receives the user request and if the URL conforms to the OData
specification, the request is delegated to the processor implementation of the
OData service.
+This means that the handler has to be configured with all processor
implementations that have been created along with the OData service (in our
example, only one processor).
+Furthermore, the <em>ODataHttpHandler</em> needs to carry the knowledge about
the <em>EdmProvider</em>.</p>
+<p>As such, hereâs the location where our 2 implemented classes come
together, the metadata declaration and the data provisioning.</p>
+<p>```java
+// This class represents a standard HttpServlet implementation.
+// It is used as main entry point for the web application that carries the
OData service.
+// The implementation of this HttpServlet simply delegates the user requests
to the ODataHttpHandler
+public class DemoServlet extends HttpServlet {</p>
+<div class="codehilite"><pre><span class="n">private</span> <span
class="n">static</span> <span class="n">final</span> <span
class="n">long</span> <span class="n">serialVersionUID</span> <span
class="p">=</span> 1<span class="n">L</span><span class="p">;</span>
+<span class="n">private</span> <span class="n">static</span> <span
class="n">final</span> <span class="n">Logger</span> <span class="n">LOG</span>
<span class="p">=</span> <span class="n">LoggerFactory</span><span
class="p">.</span><span class="n">getLogger</span><span class="p">(</span><span
class="n">DemoServlet</span><span class="p">.</span><span
class="n">class</span><span class="p">);</span>
+
+<span class="p">@</span><span class="n">Override</span>
+<span class="n">protected</span> <span class="n">void</span> <span
class="n">service</span><span class="p">(</span><span class="n">final</span>
<span class="n">HttpServletRequest</span> <span class="n">req</span><span
class="p">,</span> <span class="n">final</span> <span
class="n">HttpServletResponse</span> <span class="n">resp</span><span
class="p">)</span> <span class="n">throws</span> <span
class="n">ServletException</span><span class="p">,</span> <span
class="n">IOException</span> <span class="p">{</span>
+
+ <span class="k">try</span> <span class="p">{</span>
+ <span class="o">//</span> <span class="n">create</span> <span
class="n">odata</span> <span class="n">handler</span> <span
class="n">and</span> <span class="n">configure</span> <span class="n">it</span>
<span class="n">with</span> <span class="n">EdmProvider</span> <span
class="n">and</span> <span class="n">Processor</span>
+ <span class="n">OData</span> <span class="n">odata</span> <span
class="p">=</span> <span class="n">OData</span><span class="p">.</span><span
class="n">newInstance</span><span class="p">();</span>
+ <span class="n">ServiceMetadata</span> <span class="n">edm</span>
<span class="p">=</span> <span class="n">odata</span><span
class="p">.</span><span class="n">createServiceMetadata</span><span
class="p">(</span><span class="n">new</span> <span
class="n">ExampleEdmProvider</span><span class="p">(),</span> <span
class="n">new</span> <span class="n">ArrayList</span><span
class="o"><</span><span class="n">EdmxReference</span><span
class="o">></span><span class="p">());</span>
+ <span class="n">ODataHttpHandler</span> <span class="n">handler</span>
<span class="p">=</span> <span class="n">odata</span><span
class="p">.</span><span class="n">createHandler</span><span
class="p">(</span><span class="n">edm</span><span class="p">);</span>
+ <span class="n">handler</span><span class="p">.</span><span
class="n">register</span><span class="p">(</span><span class="n">new</span>
<span class="n">DemoEntityCollectionProcessor</span><span class="p">());</span>
+
+ <span class="o">//</span> <span class="n">let</span> <span
class="n">the</span> <span class="n">handler</span> <span class="n">do</span>
<span class="n">the</span> <span class="n">work</span>
+ <span class="n">handler</span><span class="p">.</span><span
class="n">process</span><span class="p">(</span><span class="n">req</span><span
class="p">,</span> <span class="n">resp</span><span class="p">);</span>
+
+ <span class="p">}</span> <span class="k">catch</span> <span
class="p">(</span><span class="n">RuntimeException</span> <span
class="n">e</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LOG</span><span class="p">.</span><span
class="n">error</span><span class="p">(</span>"<span
class="n">Server</span> <span class="n">Error</span> <span
class="n">ocurred</span> <span class="n">in</span> <span
class="n">DemoServlet</span>"<span class="p">,</span> <span
class="n">e</span><span class="p">);</span>
+ <span class="n">throw</span> <span class="n">new</span> <span
class="n">ServletException</span><span class="p">(</span><span
class="n">e</span><span class="p">);</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>}</p>
+<p>```</p>
+<h3 id="432-edit-the-webxml">4.3.2. Edit the web.xml</h3>
+<p>The very last step of our tutorial is to register the Servlet in the
<em>web.xml</em> file.<br />
+Furthermore, we need to specify the <em>url-pattern</em> for the servlet, such
that our OData service can be invoked.</p>
+<p>Open the <em>src/main/webapp/WEB-INF/web.xml</em> file and paste the
following content into it:</p>
+<p>```xml
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="WebApp_ID" version="2.5"></p>
+<p><servlet>
+ <servlet-name>DemoServlet</servlet-name>
+ <servlet-class> myservice.mynamespace.web.DemoServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+</servlet></p>
+<p><servlet-mapping>
+ <servlet-name>DemoServlet</servlet-name>
+ <url-pattern>/DemoService.svc/*</url-pattern>
+</servlet-mapping>
+</web-app></p>
+<p>```</p>
+<p>Thatâs it. Now we can build and run the web application.</p>
+<hr />
+<h1 id="5-run-the-service">5. Run the service</h1>
+<p>Running the service means build the war file and deploy it on a server.<br
/>
+In our tutorial, weâre using the Eclipse web integration tools, which make
life easier.</p>
+<h3 id="run-with-eclipse">Run with Eclipse</h3>
+<p>Select your project and from the context menu choose <em>Run As -> Run
on Server</em><br />
+If you donât have any server configured in Eclipse, you have to âmanually
define a new serverâ in the subsequent dialog.<br />
+If you have installed a Tomcat server on your local file system, you can use
it here.<br />
+If not, you can use the <em>Basic -> J2EE Preview</em> option, which is
should be enough for our tutorial. </p>
+<p><img alt="runOnServer" src="runOnServer.png" title="The Eclipse dialog for
deploying web apps to a server" /></p>
+<blockquote>
+<p>Note:
+You might have to first execute maven build and also press F5 to refresh the
content of the Eclipse project</p>
+</blockquote>
+<p>After pressing "run", Eclipse starts the internal server and deploys the
web application on it.
+Then the Eclipse internal Browser View is opened and the index.jsp file that
has been generated into our Example project is opened.<br />
+We ignore it. Instead, we open our OData service in our favorite browser.</p>
+<blockquote>
+<p>Note:
+If you face problems related to the server, it helps to restart your Eclipse
IDE.</p>
+</blockquote>
+<h3 id="the-service-urls">The service-URLs</h3>
+<p>Try the following URLs:</p>
+<p><strong>Service Document</strong></p>
+<p><code>http://localhost:8080/DemoService/DemoService.svc/</code>
+The expected result is the service document which displays our
<em>EntityContainerInfo</em>:</p>
+<p><code>json
+{
+ "@odata.context" :
"http://localhost:8080/DemoService/DemoService.svc/$metadata",
+ "value" : [
+ {
+ "name" : "Products",
+ "url" : "Products"
+ } ]
+}</code></p>
+<p><strong>Metadata Document</strong></p>
+<p><code>http://localhost:8080/ExampleService1/ExampleService1.svc/$metadata</code>
+The expected result is the metadata document that displays our
<em>Schema</em>, <em>EntityType</em>, <em>EntityContainer</em> and
<em>EntitySet</em>.</p>
+<p><code>xml
+<?xml version='1.0' encoding='UTF-8'?>
+<edmx:Edmx Version="4.0"
xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
+ <edmx:DataServices>
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
Namespace="com.example.model">
+ <EntityType Name="Product">
+ <Key>
+ <PropertyRef Name="ID"/>
+ </Key>
+ <Property Name="ID" Type="Edm.Int32"/>
+ <Property Name="Name" Type="Edm.String"/>
+ <Property Name="Description" Type="Edm.String"/>
+ </EntityType>
+ <EntityContainer Name="Container">
+ <EntitySet Name="Products"
EntityType="com.example.model.Product"/>
+ </EntityContainer>
+ </Schema>
+ </edmx:DataServices>
+</edmx:Edmx></code></p>
+<p><strong>Query / EntitySet</strong></p>
+<p><code>http://localhost:8080/DemoService/DemoService.svc/Products</code>
+The expected result is the hardcoded list of product entries, which we have
coded in our processor implementation:</p>
+<p><code>json
+{
+ "@odata.context":"$metadata#Products","
+ value":[
+ {
+ "ID":1,
+ "Name":"Notebook Basic 15",
+ "Description":"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM -
40GB"
+ },
+ {
+ "ID":2,
+ "Name":"1UMTS PDA",
+ "Description":"Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"
+ },
+ {
+ "ID":3,
+ "Name":"Ergo Screen",
+ "Description":"17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280
x 960"
+ }]
+}</code></p>
+<hr />
+<h1 id="6-summary">6. Summary</h1>
+<p>Finally, weâve created our first OData service based on the V4 version of
the OData specification and using the V4 server library provided by
<em>Olingo</em>.<br />
+Our first OData service is very simple; it only allows invoking one entity
collection, apart from the service document and the metadata document.</p>
+<p><strong>Outlook</strong></p>
+<p>Further topics to be covered by follow-up tutorials:<br />
+<em> READ scenario: reading single entity, reading property<br />
+</em> WRITE scenario: executing PUT, POST and DELETE requests<br />
+<em> Navigation: navigating from one entity to a corresponding second entity
+</em> Data types</p>
+<p><strong>Further reading</strong></p>
+<p>OData specification: http://odata.org/<br />
+Olingo Javadoc: http://olingo.apache.org/javadoc/odata4/index.html</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>