olingo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r957524 [4/5] - in /websites/staging/olingo/trunk/content: ./ doc/javascript/ doc/odata2/ doc/odata2/tutorials/ doc/odata4/ doc/odata4/tutorials/ doc/odata4/tutorials/navigation/ doc/odata4/tutorials/read/ doc/odata4/tutorials/readep/ doc/o...
Date Wed, 08 Jul 2015 13:49:35 GMT
Added: websites/staging/olingo/trunk/content/doc/odata4/tutorials/navigation/tutorial_navigation.md
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/navigation/tutorial_navigation.md (added)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/navigation/tutorial_navigation.md Wed Jul  8 13:49:34 2015
@@ -0,0 +1,911 @@
+# How to build an OData Service with Olingo V4
+
+# Part 4: Navigation
+
+## Introduction
+
+In the present tutorial, we’ll learn how to implement navigation between 2 Entity Types in an OData V4 service.
+
+**Background**  
+Say, we have an electronics shop and we have a lot of products which we’re selling and these products can be notebooks or monitors or organizers, which are the categories.  
+We would have 3 requirements:
+
+  1. We want to show a list of all our categories, then select one and display a list of all products that belong to this category, e.g. all monitors
+  In terms of OData, this is called navigation
+  2. From the list of our products, we want to choose one and display its category
+  3. We want to navigate from a category to its products and perform a READ operation on one of them.
+
+**Example for navigating in a service**  
+We open the Categories collection: <http://localhost:8080/DemoService/DemoService.svc/Categories>
+
+![CategoryCollection](browser_categories.JPG "The Category collection")
+
+We open the details of the first Category, the “Notebooks”-category:
+http://localhost:8080/DemoService/DemoService.svc/Categories(1)
+
+![CategoryEntity](browser_categories1.jpg "Read single Category entity")
+
+In order to display all products that are notebooks, we can navigate from the selected category to its products:  
+http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products
+
+![ProductsOfCategory](browser_categories1_products.jpg "After navigating from a  Category to the related Products")
+
+In the above example we’ve executed a one-to-many navigation.  
+
+As mentioned in the Background section, it is also required to navigate from a selected product to its category, which is a to-one relation, like:
+http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category
+
+And finally, it is possible to navigate to a list of products and directly access one of them, e.g.  
+http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products(1)
+
+All three cases are covered by the present tutorial.
+
+
+**Note**
+The full implementation of the OData service as described in the present tutorial can be found in the attached zip file that contains an Eclipse project that can be imported into your Eclipse workspace.
+
+**Disclaimer**
+Again, in the present tutorial, we’ll focus only on the relevant implementation, in order to keep the code small and simple.
+The sample code shouldn’t be reused for advanced scenarios.
+
+
+**Table of Contents**
+
+  1. Prerequisites
+  2. Preparation
+  3. Implementating the navigation
+    1. Declare the Metadata
+    2. Implement the to-many navigation
+    3. Implement the to-one navigation
+    4. Implement the to-many navigation with key access
+  4. Run the implemented service
+  5. Summary
+  6. Links
+  7. Appendix: code snippets
+
+
+___
+
+# 1. Prerequisites
+
+Same prerequisites as in [Tutorial Part 1: Read Entity Collection](http://olingo.apache.org/doc/odata4/tutorials/read/tutorial_read.html)
+ and [Tutorial Part 2: Read Entity](http://olingo.apache.org/doc/odata4/tutorials/readep/tutorial_readep.html) as well as basic knowledge about the concepts presented in both tutorials.
+
+___
+
+# 2. Preparation
+
+Follow Tutorial Part 1: Read Entity Collection and Tutorial Part 2: Read Entity or as shortcut import the project attached to Tutorial Part 2 into your Eclipse workspace.
+
+Afterwards do a Deploy and run: it should be working.
+
+
+___
+
+
+# 3. Implementing the navigation
+
+
+In our sample scenario, we want to navigate from a product to its category and from a category to a list of products.  
+In order to achieve this, we need to create a second Entity Type, "Category", and we need to specify _Navigation Properties_ in both Entity Types.  
+Our model looks as follows:
+
+![ODataModelNavigation](model.JPG "Our OData Model with link between 2 Entity Types")
+
+
+**Note**
+When designing the OData model, we could think of specifying a property “ProductCategory” in the entity type “Product”.
+E.g. a product with name “Brilliant flat and wide” would have the category “Monitors”.  
+But this is not necessary, because that information can be obtained by navigating to the respective “Category”-entity using the navigation property.  
+That way, we can keep the entity types lightweight, which is one of the intentions of OData.
+
+
+## 3.1. Declare the metadata
+
+In order to declare the metadata of our OData service, we open the class _myservice.mynamespace.service.DemoEdmProvider_
+
+### 3.1.1. Extend the Entity Type “Product”
+
+In the previous tutorial we’ve already created the metadata for the “Product” entity type:
+
+    :::xml
+    <EntityType Name="Product">
+        <Key>
+          <PropertyRef Name="ID" />
+        </Key>
+        <Property Name="ID" Type="Edm.Int32" Nullable="false" />
+        <Property Name="Name" Type="Edm.String" Nullable="false" />
+        <Property Name="Description" Type="Edm.String" Nullable="false" />
+    </EntityType>
+
+Now we have to add a navigation property.  
+That navigation property element has the following attributes:  
+
+
+**Name**
+Tthe name of the navigation property is used as segment in the URI  
+e.g. for the following URL: <http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category>  
+The segment “Category” is the name of the navigation property  
+
+**Type**
+Here we specify the Entity Type to which we’re navigating.  
+e.g. for the following URL: <http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category>  
+we’re navigating to an entity which has the entity type “OData.Demo.Category”  
+(we still have to create this entity type in this tutorial)  
+Note that the fully qualified name has to be specified.  
+Note that here we don’t specify a collection, so we have a to-one relationship.
+
+**Nullable**  
+Specifies if the navigation target is required.  
+If we don’t specify it, then the default is assumed to be “true”.  
+In our example we want to declare that every product must have a category, so we have to set it to “false”
+
+**Partner**  
+An optional attribute, used to define a bi-directional relationship.  
+Specifies a path from the entity type (specified here) to the navigation property (defined there).
+In our example, we can navigate from product to category and from category to product  
+
+
+In our example, the metadata of our “Product” entity type looks as follows:
+
+
+    :::xml
+     <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"/>
+       <NavigationProperty Name="Category" Type="OData.Demo.Category" Nullable="false" Partner="Products"/>
+     </EntityType>
+
+
+Implementation-wise we have to create and configure an object of type _CsdlNavigationProperty_:
+
+    :::java
+    CsdlNavigationProperty navProp = new CsdlNavigationProperty()
+                                        .setName("Category")
+                                        .setType(ET_CATEGORY_FQN)
+                                        .setNullable(false)
+                                        .setPartner("Products");
+
+Since an entity type can have multiple navigation properties, we have to put it into a list:
+
+    :::java
+    List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
+    navPropList.add(navProp);
+
+That list becomes relevant for the entity type that has been created earlier:
+
+    :::java
+    entityType.setNavigationProperties(navPropList);
+
+
+There’s one more step to consider with respect to the navigation: the entity set.  
+At runtime, we need to know how to implement the navigation, when an entity set is invoked.  
+For this purpose, the OData specifies the _NavigationPropertyBinding_ element, which is a child element of the entity set and should be defined for each navigation property.  
+That _NavigationPropertyBinding_ has the following attributes:  
+
+**Path**  
+Here we specify the name of the corresponding navigation property.
+In our example, the navigation property that we’ve defined above is named “Category”
+
+**Target**  
+Here we specify the entity set where we’re navigating to.  
+In our example it is the entity set “Categories” (which we’ll create below)
+
+In our example, the definition of our “Products” entity set looks as follows:
+
+    :::xml
+    <EntitySet Name="Products" EntityType="OData.Demo.Product">
+      <NavigationPropertyBinding Path="Category" Target="Categories"/>
+    </EntitySet>
+
+
+Code-wise, the getEntitySet method is extended as follows:
+
+    :::java
+    CsdlNavigationPropertyBinding navPropBinding = new CsdlNavigationPropertyBinding();
+    navPropBinding.setPath("Category"); // the path from entity type to navigation property
+    navPropBinding.setTarget("Categories"); //target entitySet, where the nav prop points to
+    List<CsdlNavigationPropertyBinding> navPropBindingList = new ArrayList<CsdlNavigationPropertyBinding>();
+    navPropBindingList.add(navPropBinding);
+    entitySet.setNavigationPropertyBindings(navPropBindingList);
+
+
+
+### 3.1.2. Create the Entity Type “Category”  
+
+Now we have to create the second entity type, the “Category”.  
+In order to keep our sample as simple as possible, we define only 2 properties, the “ID” and a “Name”.  
+Since we want to be able to navigate from one given category (e.g. “Monitors”) to a list of products (e.g. all products that are monitors), we have to specify a navigation property in this entity type as well.  
+Here, the navigation property has the following attributes:  
+
+**Name**  
+In our example, we specify “Products”, in plural because we want to get multiple entities.  
+
+**Type**  
+The “Type” attribute can be either an “entity type” or a “collection of entity types”  
+In our example this time, we specify a “collection” of “OData.Demo.Product”  
+
+**Nullable**  
+According to the OData specification (see odata.org), this attribute is not allowed for a collection
+A collection can be empty, but never null.
+
+**Partner**  
+In our example, we’re defining a bi-directional navigation, so here we specify “Category”, the name of the navigation property defined above.
+
+In our example, the metadata of our “Category” entity type looks as follows:
+
+    :::xml
+    <EntityType Name="Category">
+      <Key>
+        <PropertyRef Name="ID"/>
+      </Key>
+      <Property Name="ID" Type="Edm.Int32"/>
+      <Property Name="Name" Type="Edm.String"/>
+      <NavigationProperty Name="Products" Type="Collection(OData.Demo.Product)" Partner="Category"/>
+    </EntityType>
+
+
+The code for the “Category” entity type:
+
+    :::java
+    if (entityTypeName.equals(ET_CATEGORY_FQN)){
+	    //create EntityType properties
+	    CsdlProperty id = new CsdlProperty()
+                                .setName("ID")
+                                .setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+	    CsdlProperty name = new CsdlProperty()
+                                .setName("Name")
+                                .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+
+	    // create PropertyRef for Key element
+	    CsdlPropertyRef propertyRef = new CsdlPropertyRef();
+	    propertyRef.setName("ID");
+
+	    // navigation property: one-to-many
+	    CsdlNavigationProperty navProp = new CsdlNavigationProperty()
+                                .setName("Products")
+                                .setType(ET_PRODUCT_FQN)
+                                .setCollection(true)
+                                .setPartner("Category");
+	    List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
+	    navPropList.add(navProp);
+
+    	// configure EntityType
+    	entityType = new CsdlEntityType();
+    	entityType.setName(ET_CATEGORY_NAME);
+    	entityType.setProperties(Arrays.asList(id, name));
+    	entityType.setKey(Arrays.asList(propertyRef));
+    	entityType.setNavigationProperties(navPropList);
+    }
+
+
+The _NavigationPropertyBinding_ element and its attributes for the entity set “Categories”:  
+
+**Path**  
+In our example, the navigation property that we’ve defined above is named “Products”
+
+**Target**  
+In our example it is the entity set “Products”
+
+
+In our example, the definition of our “Categories” entity set looks as follows:
+
+    :::xml
+    <EntitySet Name="Categories" EntityType="OData.Demo.Category">
+      <NavigationPropertyBinding Path="Products" Target="Products"/>
+    </EntitySet>
+
+And the implementation in the _getEntitySet_ method:
+
+    :::java
+    CsdlNavigationPropertyBinding navPropBinding = new CsdlNavigationPropertyBinding();
+    navPropBinding.setTarget("Products");//target entitySet, where the nav prop points to
+    navPropBinding.setPath("Products"); // the path from entity type to navigation property
+    List<CsdlNavigationPropertyBinding> navPropBindingList = new ArrayList<CsdlNavigationPropertyBinding>();
+    navPropBindingList.add(navPropBinding);
+    entitySet.setNavigationPropertyBindings(navPropBindingList);
+
+
+
+---
+
+
+## 3.2. Implement the to-many navigation
+
+Let’s again have a look at our example, as described in the introduction section above.
+The user of our service invokes the “Categories” collection and chooses one “Category”.  
+This is done with e.g. the following URL: <http://localhost:8080/DemoService/DemoService.svc/Categories(1)>
+
+The returned response payload doesn’t contain any information about possible navigation.  
+So the user has to check the metadata document, where he can see that the entity type “Category” defines one navigation property:  
+
+![CategoryMetadata](browser_metadataCategory.JPG "The definition of a Navigation Property in the $metadata document")
+
+This means, that he can append the navigation property name to his URL, which takes him to the set of “Products” that belong to the chosen “Category”: <http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products>
+
+From the metadata we can see that the “Type” attribute defines a collection.  
+This means that the implementation has to be done in the _EntityCollectionProcessor_, since we have to provide a collection of entities.
+
+Open the class `myservice.mynamespace.service.DemoEntityCollectionProcessor.java`
+
+There, the implementation for a “normal” read operation is already in place and we have to add the case when an entity collection is expected after navigation.  
+Note that we want to keep our tutorial and our code simple, so we decide that only one step navigation is to be supported by our service.  
+This means that we can navigate only once from one entity to another one.  
+For example:  
+Categories(1)/Products  
+We don’t support navigation from one entity to an entity and then to another entity and so on  
+For example:
+Categories(1)/Products(1)/Category  
+
+Based on this assumption, in our _EntityCollectionProcessor_, we can rely on the fact that the URI can have either one or two segments.  
+This means: we can be called for the following kind of URLs:  
+
+Example URL for one sement: <http://localhost:8080/DemoService/DemoService.svc/Categories>  
+
+Example URL for two segments: <http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products>
+
+As such, in our code we distinguish these 2 cases:
+
+    :::java
+    if(segmentCount == 1){
+        // here the “normal” entity set is requested
+    }else if (segmentCount == 2){
+        // this is reached in case of navigation: DemoService.svc/Categories(1)/Products
+    }else{
+        // in our example, we don’t support URIs like Products(1)/Category/Products
+        throw new ODataApplicationException("Not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ENGLISH);
+    }
+
+
+The segments of the URI are retrieved from the uriInfo parameter:
+
+    :::java
+    List<UriResource> resourceParts = uriInfo.getUriResourceParts();
+    int segmentCount = resourceParts.size();
+
+In both cases, we have to retrieve the list of entities to be returned.  
+For the first case, we have only one entitySet, so the implementation is straight forward:
+
+    :::java
+    EdmEntitySet startEdmEntitySet = uriResourceEntitySet.getEntitySet();
+    if(segmentCount == 1) {
+        // 2nd: fetch the data from backend for this requested EntitySetName
+        responseEntityCollection = storage.readEntitySetData(responseEdmEntitySet);
+        responseEdmEntitySet = startEdmEntitySet; //there’s only one entity set
+    }
+
+
+Now let’s focus on the second case, the navigation.
+
+Our tasks are:
+  1. depending on the chosen key of the first segment, we have to compute which and how many entities exactly have to be returned. With other words, find the right data in the backend  
+  e.g. for the category “monitors”, we have to find the right products that are monitors
+  2. find out, which entity set has to be returned (can be products, categories, etc)  
+  This _EdmEntitySet_ is required in order to properly build the context URL
+
+The following sections explain how to do that.
+
+### 3.2.1. Get the data for the response
+
+Getting the data for the response is reylized in 2 steps:  
+
+
+**A)** get the data for the first URI segment  
+in our example, we have to perform a read operation for retrieving the Category with ID 3, which is "Monitors"  
+
+**B)** get the data for the navigation  
+in our example, we have to find the products that are monitors.  
+
+With respect to data, remember that we're using sample data that we create in our Storage class which represents our kind of database-mock.  
+On startup of our service, we initialize some sample products and categories.  
+During initialization, there’s no assignment of products to its categories.  
+In our sample code, we’re doing this when requested in a hard-coded method in our _Storage_ class.  
+
+
+**A) get the data for the first URI segment**
+
+In our example, the URL would be: <http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products>  
+For this example, we would have to retrieve the Category with ID=3  
+The code looks like a normal READ operation:  
+
+    :::java
+    List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+    Entity sourceEntity = storage.readEntityData(startEdmEntitySet, keyPredicates);
+
+In our example, the result is an entity that represents the “Monitors” – category.
+
+
+**B) get the data for the navigation**
+
+Now we have to follow the navigation, based on the retrieved entity.  
+In our example, we have to retrieve all products that are monitors.  
+
+This is backend logic, so we can directly call a helper method in our Storage class:  
+
+    :::java  
+    responseEntityCollection = storage.getRelatedEntityCollection(sourceEntity, targetEntityType);
+
+This helper method requires the source entity and returns the target collection.  
+Additionally, the method needs the _EdmEntityType_ that corresponds to the requested target.  
+In our example, we pass the “Category” (i.e. "Monitors") as source entity and the navigation target entity type, which is “Product”.  
+As a result, we get the desired “Products” collection, all products that are monitors.  
+
+After this step, we’re almost done, because we have the entity collection that our OData service returns in the response body.  
+We only need to do some more hand work: the response entity collection has to be serialized and the serializer which is in charge of doing that has to be configured properly.  
+For that we need the _EdmEntitySet_ that corresponds to the response.  
+Since it is different in case of navigation and non-navigation, we still need to retrieve it for the case of navigation.  
+
+
+### 3.2.2. Retrieve the EdmEntitySet for the response
+
+First, we have to analyze the URI, and find out if the URI segment is used for navigation.  
+As mentioned, in our simple example we assume that the second segment is used for navigation (in advanced services, a segment could as well be an action or function import, etc).  
+The navigation URI segment can then be asked for the corresponding _EdmNavigationProperty_  
+
+    :::java
+    UriResource lastSegment = resourceParts.get(1);
+    if(lastSegment instanceof UriResourceNavigation){
+	    UriResourceNavigation uriResourceNavigation = (UriResourceNavigation)lastSegment;
+	    EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
+
+
+The bad news is that the _EdmNavigationProperty_ doesn’t know about the target _EdmEntitySet_.  
+This is as per design, just check the metadata:
+
+    :::xml
+    <EntityType Name="Category">
+	    ...
+	    <NavigationProperty Name="Products" Type="Collection(OData.Demo.Product)" Partner="Category"/>
+    </EntityType>
+
+
+The navigation property is defined on entity-type-level and as such, it does know the target entity type.  
+The target entity set is defined in the navigation property binding element on entity-set-level:  
+
+    :::xml
+    <EntitySet Name="Categories" EntityType="OData.Demo.Category">
+	    <NavigationPropertyBinding Path="Products" Target="Products"/>
+    </EntitySet>
+
+This is where we get the information that we need.  
+
+For our implementation, this means:
+  1. we need the _EdmEntiySet_ that corresponds to the first segment of the URI
+  	in our example: Categories
+  2. we need the navigation property that corresponds to the second segment of the URI
+  	in our example: Products
+
+As shown below, from the source _EdmEntitySet_ we get the binding target, based on the navigation property.  
+
+    :::java
+    EdmBindingTarget edmBindingTarget = startEntitySet.getRelatedBindingTarget(navPropName);
+    if(edmBindingTarget instanceof EdmEntitySet){
+	    navigationTargetEntitySet = (EdmEntitySet)edmBindingTarget;
+
+This target is the entity set that we need.  
+
+We move the code into the utility method _Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty)_
+Reason is that we'll need it again, later in this tutorial.  
+
+### 3.2.3 Remaining tasks
+
+In the previous tutorials we’ve already learned what else has to be done: transform the retrieve data into an _InputStream_ i.e. serialize the content.
+Furthermore, configure the response object, i.e. set the response body, the content type and the header.  
+
+
+The following snippet shows the implementation of the _readEntityCollection(…)_ method.
+
+    :::java
+public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
+                                    throws ODataApplicationException, SerializerException {
+
+	EdmEntitySet responseEdmEntitySet = null; // for building ContextURL
+	EntityCollection responseEntityCollection = null; // for the response body
+
+	// 1st retrieve the requested EntitySet from the uriInfo
+	List<UriResource> resourceParts = uriInfo.getUriResourceParts();
+	int segmentCount = resourceParts.size();
+
+	UriResource uriResource = resourceParts.get(0); // the first segment is the EntitySet
+	if (! (uriResource instanceof UriResourceEntitySet)) {
+		throw new ODataApplicationException("Only EntitySet is supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
+	}
+
+	UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) uriResource;
+	EdmEntitySet startEdmEntitySet = uriResourceEntitySet.getEntitySet();
+
+	if(segmentCount == 1){ // this is the case for: DemoService/DemoService.svc/Categories
+		responseEdmEntitySet = startEdmEntitySet; // first (and only) entitySet
+
+		// 2nd: fetch the data from backend for this requested EntitySetName
+		responseEntityCollection = storage.readEntitySetData(startEdmEntitySet);
+	}else if (segmentCount == 2){ //navigation: e.g. DemoService.svc/Categories(3)/Products
+		UriResource lastSegment = resourceParts.get(1); // don't support more complex URIs
+		if(lastSegment instanceof UriResourceNavigation){
+			UriResourceNavigation uriResourceNavigation = (UriResourceNavigation)lastSegment;
+			EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
+			EdmEntityType targetEntityType = edmNavigationProperty.getType();
+			responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
+
+			// 2nd: fetch the data from backend
+			// first fetch the entity where the first segment of the URI points to
+            // e.g. Categories(3)/Products first find the single entity: Category(3)
+			List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+			Entity sourceEntity = storage.readEntityData(startEdmEntitySet, keyPredicates);
+			// error handling for e.g.  DemoService.svc/Categories(99)/Products
+			if(sourceEntity == null) {
+                throw new ODataApplicationException("Entity not found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+			}
+			// then fetch the entity collection where the entity navigates to
+			responseEntityCollection = storage.getRelatedEntityCollection(sourceEntity, targetEntityType);
+		}
+	}else{ // this would be the case for e.g. Products(1)/Category/Products
+		throw new ODataApplicationException("Not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
+	}
+
+	// 3rd: create and configure a serializer  
+	ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).build();
+	EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).build();
+	EdmEntityType edmEntityType = responseEdmEntitySet.getEntityType();
+
+	ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(responseFormat));
+	SerializerResult serializerResult = serializer.entityCollection(this.srvMetadata, edmEntityType, responseEntityCollection, opts);
+
+	// 4th: configure the response object: set the body, headers and status code
+	response.setContent(serializerResult.getContent());
+	response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+	response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+}
+
+## 3.3. Implement the to-one navigation
+
+As for the to-one navigation, it is the case if the navigation target is a single entity, not a collection.  
+In our example, the following URL represents a to-one navigation: <http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category>  
+
+The user of our service has chosen a product and wants to know to which category it belongs. He can find it out by following the navigation property.
+As per design, a product can only belong to **one** category (obviously, a product can only be a Notebook or a Monitor, not both). Therefore in our service, we’ve defined a navigation property that is not of type collection:  
+
+    :::xml
+    <NavigationProperty
+        Name="Category"
+        Type="OData.Demo.Category"
+        Nullable="false"
+        Partner="Products"/>
+
+So when the user follows the navigation property in order to display the product category, he expects a response that contains only one entry.  
+This means that we have to do the implementation in the _EntityProcessor_.
+
+Open the class _myservice.mynamespace.service.DemoEntityProcessor.java_
+
+As usual, we first have to analyze the URI.  
+Just like we did in the _EntityCollectionProcessor_, we have to distinguish between navigation and “normal” read of an entity:  
+
+    :::java
+    if(segmentCount == 1){
+        // in case of directly adressing of an entity
+    }else if (segmentCount == 2){
+        // this is reached in case of navigation
+    }
+
+In the following section, we’ll focus on the navigation case only.  
+In our example, our task is to find the category of a chosen product.  
+Again, we have to first fetch the chosen product (first URI segment) from our database-mock and in a second step, we have to ask our database-mock for the corresponding category.  
+This final entity is then serialized and set as response body for the _readEntity_ method, which we’re implementing.  
+
+**A) get the data for the first URI segment**
+
+In our example, we have to perform a read operation for retrieving the product with ID 1: <http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category>  
+
+The code is the same like in the previous chapter (to-many navigation):  
+
+    :::java
+    List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+    Entity sourceEntity = storage.readEntityData(startEdmEntitySet, keyPredicates);
+
+
+**B) get the data for the navigation**
+
+Now we have to follow the navigation, based on the retrieved entity.  
+In our example, we have to find the category corresponding to the chosen product.  
+Therefore, we invoke our helper method and pass the source Entity (Product) and the required target entity type (Category). The method will find the category which is related to the chosen product.  
+
+    :::java
+    responseEntity = storage.getRelatedEntity(sourceEntity, responseEdmEntityType);
+
+Before we can serialize the _responseEntity_, we have to retrieve the _EdmEntitySet_ that corresponds to the response entity, because we need it for building the ContextURL.
+
+The procedure is the same like in the chapter above, where we treated the to-many navigation:
+
+    :::java
+    EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
+    responseEdmEntityType = edmNavigationProperty.getType();
+    responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
+
+In our example, the value of the variable _responseEdmEntitySet_ will be “Categories” and it will be used for building the contextURL, which will look as follows:
+
+    :::xml  
+    "$metadata#Categories/$entity"
+
+
+## 3.4. Implement the to-many navigation with key access
+
+"Navigation with key access" means that we have a to-many navigation, like navigating from a chosen category to the list of corresponding products: <http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products>
+
+but in addition, we want to read only one of the collected products, which is directly addressed by its key:   <http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products(5)>
+
+From this URL, we can assume that the _EntityProcessor.java_ is the relevant place to handle this request in our code.  
+
+The steps to find the requested entity are:  
+
+  1. Do a read operation for the first segment (same as in the previous chapter)  
+  In our example, this would be read entity for: */Categories(3)*
+  2. Follow the navigation to get the collection of the second segment  
+  In our example, this would be get the entity collection for: */Categories(3)/Products*
+  3. Pick the requested entity from the collection  
+  In our example, retrieve the product with ID=5, which is contained in the collection */Categories(3)/Products(5)*
+
+
+
+We can assume, that our database-mock is able to perform step 2 and 3 together.
+
+In our class _myservice.mynamespace.service.DemoEntityProcessor.java_, we’ve already added the navigation capability for to-one navigation.
+How can we find out that we aren’t called for a to-one navigation, but instead, we’re responding to a to-many navigation with key access?  
+The difference is the “key predicate”.  
+The necessary info about it can be obtained from the URI segment.  
+In the first chapter, we’ve already learned that there’s a special interface responsible for navigation segments, the _org.apache.olingo.server.api.uri.UriResourceNavigation_  
+It also provides a method _getKeyPredicates()_
+We can make use of it in order to distinguish between “to-one navigation” and “navigation with key access”.  
+If the call to
+
+    :::java
+    List<UriParmeter> navKeyPredicates = uriResourceNavigation.getKeyPredicates();
+
+returns an empty list, then we can assume that our OData service has been called for a “to-one navigation”.  
+This to-one navigation has been explained in the chapter 3.3. above.
+If  the service request is like
+/Categories(3)/Products(5)  
+then the method _getKeyPredicates()_ will return a list of with one element that contains ID=5
+
+In our implementation of the _EntityProcessor_, we add the following code:
+
+    :::java
+    List<UriParameter> navKeyPredicates = uriResourceNavigation.getKeyPredicates();
+    if(navKeyPredicates.isEmpty()){
+	    responseEntity = storage.getRelatedEntity(sourceEntity, responseEdmEntityType);
+    }else{
+	    responseEntity = storage.getRelatedEntity(sourceEntity, responseEdmEntityType, navKeyPredicates);
+    }
+
+We get the key predicates for the navigation segment.  
+Then we check if returned list is empty.  
+If yes, we use the line that we implemented in chapter 3.3.  
+If not, we have to create a new helper method that uses the key predicates for retrieving the desired entity.  
+The new helper method
+
+    :::java
+    responseEntity = storage.getRelatedEntity(sourceEntity, responseEdmEntityType, navKeyPredicates);
+
+will take care of getting the collection of products (_responseEntityType_) that are in scope of the chosen category (_sourceEntity_) and will then pick the requested product, based on the given key (_navKeyPredicates_).
+
+One last thing to consider:
+As we mentioned above, the user of our service is expected to specify a key of a product that is contained in the collection of products that is addressed by e.g.
+/Categories(3)/Products  
+e.g.
+/Categories(3)/Products(5)  
+But he might specify a product ID that is existing, but not valid for the addressed navigation.
+e.g.
+/Categories(3)/Products(1)  
+With other words: it is not valid to navigate from category "Monitors" to a product like "Notebook Basic 15"
+
+If this is the case, we have to throw an appropriate exception.  
+However, in our simple example we’re satisfied with simply checking if an entity was found at all:
+
+    :::java
+    if(responseEntity == null) {
+	    throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+    }
+
+**Note**  
+When implementing this navigation for the first time, our first intention might have been:  
+Let’s just ignore the first segment and simply do a read operation for /Products(5)  
+Which would mean, from the list of all products, pick the one with ID=5  
+Why not?  
+The answer is that we cannot assume that the requested Product is automatically belonging to the specified Category.
+E.g. in our example, the following URI should throw an error:
+Categories(3)/Products(1)  
+As we know, Categories(3) is “Monitors” and Product(1) is a “Notebook”  
+
+
+That’s it.
+We don’t need to do an additional effort to retrieve the _EdmEntitySet_ for the ContextURL, because this has already been implemented in our _DemoEntityProcessor_ in the context of the previous chapter 3.3.
+
+
+So now we can finally have a look at the full implementation of the _readEntity()_ method, the covers both the cases of chapter 3.3. and 3.4.
+
+    :::java
+    public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
+				throws ODataApplicationException, SerializerException {
+
+
+    	EdmEntityType responseEdmEntityType = null; // we'll need this to build the ContextURL
+    	Entity responseEntity = null; // required for serialization of the response body
+    	EdmEntitySet responseEdmEntitySet = null; // we need this for building the contextUrl
+
+    	// 1st step: retrieve the requested Entity:
+        // can be "normal" read operation, or navigation (to-one)
+    	List<UriResource> resourceParts = uriInfo.getUriResourceParts();
+    	int segmentCount = resourceParts.size();
+
+    	UriResource uriResource = resourceParts.get(0);
+    	if (! (uriResource instanceof UriResourceEntitySet)) {
+    		throw new ODataApplicationException("Only EntitySet is supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),
+    		                                        Locale.ROOT);
+    	}
+
+    	UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) uriResource;
+    	EdmEntitySet startEdmEntitySet = uriResourceEntitySet.getEntitySet();
+
+    	// Analyze the URI segments
+    	if(segmentCount == 1){  // no navigation
+    		responseEdmEntityType = startEdmEntitySet.getEntityType();
+    		responseEdmEntitySet = startEdmEntitySet; // since we have only one segment
+
+    		// 2. step: retrieve the data from backend
+    		List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+    		responseEntity = storage.readEntityData(startEdmEntitySet, keyPredicates);
+    	} else if (segmentCount == 2){ //navigation
+    		UriResource navSegment = resourceParts.get(1);
+    		if(navSegment instanceof UriResourceNavigation){
+    			UriResourceNavigation uriResourceNavigation = (UriResourceNavigation) navSegment;
+    			EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
+    			responseEdmEntityType = edmNavigationProperty.getType();
+    			responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
+
+    			// 2nd: fetch the data from backend.
+                // for:  Products(1)/Category  we have to find the correct Category entity
+    			List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+                // e.g. for Products(1)/Category we have to find first the Products(1)
+    			Entity sourceEntity = storage.readEntityData(startEdmEntitySet, keyPredicates);
+
+    			// now we have to check if the navigation is
+    			// a) to-one: e.g. Products(1)/Category
+    			// b) to-many with key: e.g. Categories(3)/Products(5)
+    			List<UriParameter> navKeyPredicates = uriResourceNavigation.getKeyPredicates();
+
+    			if(navKeyPredicates.isEmpty()){
+                    // e.g. DemoService.svc/Products(1)/Category
+    				responseEntity = storage.getRelatedEntity(sourceEntity, responseEdmEntityType);
+    			}else{ // e.g. DemoService.svc/Categories(3)/Products(5)
+    				responseEntity = storage.getRelatedEntity(sourceEntity, responseEdmEntityType, navKeyPredicates);
+    			}
+    		}
+    	}else{
+    		// this would be the case for e.g. Products(1)/Category/Products(1)/Category
+    		throw new ODataApplicationException("Not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+    	}
+
+    	if(responseEntity == null) {
+    		// this is the case for e.g. DemoService.svc/Categories(4) or
+            // DemoService.svc/Categories(3)/Products(999)
+    		throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+    	}
+
+    	// 3. serialize
+    	ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).suffix(Suffix.ENTITY).build();
+    	EntitySerializerOptions opts = EntitySerializerOptions.with().contextURL(contextUrl).build();  
+
+    	ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
+    	ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
+    	SerializerResult serializerResult = serializer.entity(this.srvMetadata, responseEdmEntityType, responseEntity, opts);
+
+    	//4. configure the response object
+    	response.setContent(serializerResult.getContent());
+    	response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    	response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+    }
+
+---
+
+# 4. Run the implemented service
+
+After building and deploying your service to your server, you can try the following URLs:  
+
+  * Metadata and Service documents  
+    * <http://localhost:8080/DemoService/DemoService.svc/$metadata>
+    * <http://localhost:8080/DemoService/DemoService.svc>
+  * “Normal” query of both entity sets  
+    * <http://localhost:8080/DemoService/DemoService.svc/Products>
+    * <http://localhost:8080/DemoService/DemoService.svc/Categories>
+  * “Normal” read of both entity types  
+    * <http://localhost:8080/DemoService/DemoService.svc/Products(1)>
+    * <http://localhost:8080/DemoService/DemoService.svc/Categories(3)>
+  * “to-many” navigation  
+    * <http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products>
+  * “to-one” navigation  
+    * <http://localhost:8080/DemoService/DemoService.svc/Products(1)/Category>
+  * “to-many” navigation with key access  
+    * <http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products(2)>
+  * “to-many” navigation with key access of invalid key, throwing an error  
+    * <http://localhost:8080/DemoService/DemoService.svc/Categories(1)/Products(3)>
+
+
+---
+
+# 5. Summary
+
+In this tutorial we have learned how to add navigation capabilities to an OData service.  
+We’ve implemented the to-many and to-one relationship and also the READ access to one entity after a to-many navigation.  
+We’ve restricted the navigation to two segments, no more than navigating from one entity to another one.  
+The modification of relations has not been covered by this tutorial.
+Check the *Links* section for more OData V4 tutorials.  
+
+---
+
+# 6. Links
+
+Tutorial OData V4 service, part 1: [Read Entity Collection](/doc/odata4/tutorials/read/tutorial_read.html) | [sample project zip](http://olingo.apache.org/doc/odata4/tutorials/read/sample/DemoService_Tutorial_Read.zip)  
+Tutorial OData V4 service, part 2: [Read Entity, Read Property](/doc/odata4/tutorials/readep/tutorial_readep.html) | [sample project zip](http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip)  
+Tutorial OData V4 service, part 3: [Write (Create, Update, Delete Entity)](/doc/odata4/tutorials/write/tutorial_write.html) | [sample project zip](http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Write.zip)
+Tutorial OData V4 service, part 4: Navigation (this page) | sample project zip
+Tutorial OData V4 service, part 5: System Query Options  (to be announced)
+
+OData specification: http://odata.org/
+Olingo Javadoc: http://olingo.apache.org/javadoc/odata4/index.html
+
+---
+
+# 7. Appendix: code snippets
+
+When reaching the point where your OData service has to become productive and support complex scenarions, you’ll find the following code snippets useful.  
+
+## 7.1. Find the EdmEntitySet for the navigation target
+
+    :::java
+    public static EdmEntitySet getNavigationTargetEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
+
+    	EdmEntitySet entitySet;
+    	final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+
+    	// First must be entity set (hence function imports are not supported here).
+    	if (resourcePaths.get(0) instanceof UriResourceEntitySet) {
+    		entitySet = ((UriResourceEntitySet) resourcePaths.get(0)).getEntitySet();
+    	} else {
+    		throw new ODataApplicationException("Invalid resource type.",
+    				HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+    	}
+
+    	int navigationCount = 0;
+    	while (entitySet != null
+    		&& ++navigationCount < resourcePaths.size()
+    		&& resourcePaths.get(navigationCount) instanceof UriResourceNavigation) {
+    		final UriResourceNavigation uriResourceNavigation = (UriResourceNavigation) resourcePaths.get(navigationCount);
+    		final EdmBindingTarget target = entitySet.getRelatedBindingTarget(uriResourceNavigation.getProperty().getName());
+    		if (target instanceof EdmEntitySet) {
+    			entitySet = (EdmEntitySet) target;
+    		} else {
+    			throw new ODataApplicationException("Singletons not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),
+    			                                     Locale.ROOT);
+    		}
+    	}
+
+    	return entitySet;
+    }
+
+## 7.2. Find the last navigation segment
+
+    :::java
+    public static UriResourceNavigation getLastNavigation(final UriInfoResource uriInfo) {
+
+    	final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+    	int navigationCount = 1;
+    	while (navigationCount < resourcePaths.size()
+    		&& resourcePaths.get(navigationCount) instanceof UriResourceNavigation) {
+    		navigationCount++;
+    	}
+
+    	return (UriResourceNavigation) resourcePaths.get(--navigationCount);
+    }

Propchange: websites/staging/olingo/trunk/content/doc/odata4/tutorials/navigation/tutorial_navigation.md
------------------------------------------------------------------------------
    svn:executable = *

Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_client_read.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_client_read.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_client_read.html Wed Jul  8 13:49:34 2015
@@ -86,9 +86,20 @@
 
 			</div><!--/.nav-collapse -->
         </div><!--/.container-fluid -->
-      </div><!-- Main component for a primary marketing message or call to action --><h1 id="client-read-scenario">Client Read Scenario</h1>
+      </div><!-- Main component for a primary marketing message or call to action --><style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h1 id="client-read-scenario">Client Read Scenario<a class="headerlink" href="#client-read-scenario" title="Permanent link">&para;</a></h1>
 <hr />
-<h3 id="how-to-guide-for-building-a-sample-odata-client-with-the-odata-40-library-for-java">How To Guide for building a Sample OData Client with the OData 4.0 Library (for Java)</h3>
+<h3 id="how-to-guide-for-building-a-sample-odata-client-with-the-odata-40-library-for-java">How To Guide for building a Sample OData Client with the OData 4.0 Library (for Java)<a class="headerlink" href="#how-to-guide-for-building-a-sample-odata-client-with-the-odata-40-library-for-java" title="Permanent link">&para;</a></h3>
 <p><strong>TBD</strong></p><div align="center">
 <p>Copyright © 2013-2015, The Apache Software Foundation<br>
 				                Apache Olingo, Olingo, Apache, the Apache feather, and

Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_read.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_read.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_read.html Wed Jul  8 13:49:34 2015
@@ -86,10 +86,21 @@
 
 			</div><!--/.nav-collapse -->
         </div><!--/.container-fluid -->
-      </div><!-- Main component for a primary marketing message or call to action --><h1 id="how-to-guide-for-building-a-sample-odata-service-with-the-odata-40-library-for-java">How To Guide for building a Sample OData service with the OData 4.0 Library (for Java)</h1>
-<h3 id="project-setup">Project setup</h3>
+      </div><!-- Main component for a primary marketing message or call to action --><style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h1 id="how-to-guide-for-building-a-sample-odata-service-with-the-odata-40-library-for-java">How To Guide for building a Sample OData service with the OData 4.0 Library (for Java)<a class="headerlink" href="#how-to-guide-for-building-a-sample-odata-service-with-the-odata-40-library-for-java" title="Permanent link">&para;</a></h1>
+<h3 id="project-setup">Project setup<a class="headerlink" href="#project-setup" title="Permanent link">&para;</a></h3>
 <p>First, we setup a simple Maven project and add all necessary dependencies.</p>
-<h5 id="maven-project">Maven project</h5>
+<h5 id="maven-project">Maven project<a class="headerlink" href="#maven-project" title="Permanent link">&para;</a></h5>
 <p>Create a new Maven project. Execute the following command in your shell.</p>
 <div class="codehilite"><pre><span class="n">mvn</span> <span class="n">archetype</span><span class="p">:</span><span class="n">generate</span> <span class="o">-</span><span class="n">DgroupId</span><span class="p">=</span><span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">olingo</span> <span class="o">-</span><span class="n">DartifactId</span><span class="p">=</span><span class="n">odata</span><span class="o">-</span><span class="n">server</span><span class="o">-</span><span class="n">sample</span> <span class="o">-</span><span class="n">DarchetypeArtifactId</span><span class="p">=</span><span class="n">maven</span><span class="o">-</span><span class="n">archetype</span><span class="o">-</span><span class="n">webapp</span> <span class="o">-</span><span class="n">DinteractiveMode</span><span class="p">=</span><span class="n">false</span>
 </pre></div>
@@ -164,7 +175,7 @@ Each of them is split into an implementa
 </pre></div>
 
 
-<h5 id="setting-up-the-web-project">Setting up the web project</h5>
+<h5 id="setting-up-the-web-project">Setting up the web project<a class="headerlink" href="#setting-up-the-web-project" title="Permanent link">&para;</a></h5>
 <p>Next, setup up the web project by replacing the <code>web.xml</code>.</p>
 <div class="codehilite"><pre><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
 
@@ -193,7 +204,7 @@ Each of them is split into an implementa
 
 
 <p>As you can see we define a servlet, which implements the OData service. In addition we define a servlet mapping and set the welcome page.</p>
-<h2 id="implementing-the-odata-service">Implementing the OData service</h2>
+<h2 id="implementing-the-odata-service">Implementing the OData service<a class="headerlink" href="#implementing-the-odata-service" title="Permanent link">&para;</a></h2>
 <p>Each Olingo OData service consists of several parts.</p>
 <ul>
 <li><strong>EdmProvider</strong>
@@ -203,7 +214,7 @@ The data provider connects the Olingo li
 <li><strong>Processor</strong>
 The processor receives, validates and deserializes requests, fetches the requested data and delivers a serialized response of the data to the client.</li>
 </ul>
-<h5 id="edmprovider">EdmProvider</h5>
+<h5 id="edmprovider">EdmProvider<a class="headerlink" href="#edmprovider" title="Permanent link">&para;</a></h5>
 <p><img alt="Figure 2: Data model" src="er.png" /></p>
 <p>OData services are described in terms of an Entity Data Model (EDM). To do so, the first step is to provide such an EDM. In this basic tutorial, we will define a class that provides an EDM instance. The EDM will be used to determine the types of the entities, properties and so on. In addition, the service can deliver a service meta-document. As we have a static model we define constants for all top level elements of the schema. The data model is shown in figure 2 as entity relationship diagram.</p>
 <p>Create a new class called <code>CarsEdmProvider</code> that inherits from <code>EdmProvider</code></p>
@@ -380,7 +391,7 @@ Override the method <code>getEntityConta
 </pre></div>
 
 
-<h5 id="servlet">Servlet</h5>
+<h5 id="servlet">Servlet<a class="headerlink" href="#servlet" title="Permanent link">&para;</a></h5>
 <p>As described in project setup, the web projects calls a servlet. Within the servlet the EDM provider has to be loaded. Create a new class CarsServlet which extends HttpServlet.</p>
 <p>In the following steps a processor and a data provider will be created.  Currently there is not processor being registered, so the default processor will be used.  The default processor is been able to display the service document and the metadata document also.</p>
 <p>Insert the following code.</p>
@@ -408,7 +419,7 @@ Override the method <code>getEntityConta
 </pre></div>
 
 
-<h5 id="conclusion">Conclusion</h5>
+<h5 id="conclusion">Conclusion<a class="headerlink" href="#conclusion" title="Permanent link">&para;</a></h5>
 <p>Conclusion
 After the implementation of the EDM Provider the web application can be executed to show the Service Document and the Metadata Document.</p>
 <ul>
@@ -418,7 +429,7 @@ After the implementation of the EDM Prov
 <li>Show the Metadata Document:  <a href="http://localhost:8080/odata-server-sample/cars.svc/$metadata">http://localhost:8080/odata-server-sample/cars.svc/$metadata</a></li>
 </ul>
 <p>The Service Document and the Meta Document are shown by the default processor implementation.</p>
-<h5 id="add-runtime-data">Add runtime data</h5>
+<h5 id="add-runtime-data">Add runtime data<a class="headerlink" href="#add-runtime-data" title="Permanent link">&para;</a></h5>
 <p>In the next steps we will implement read access to the Car and Manufacturer entries and the read access to the Cars and Manufacturers feed. As we need some basis for sample data we create a very simple data store which contains the data as well as access methods to serve the required data.</p>
 <p>We will implement some helper methods to provide a bunch of sample data.</p>
 <p>Create a new class <code>DataProvider</code>.</p>
@@ -564,7 +575,7 @@ After the implementation of the EDM Prov
 
 
 <p>The method DataProvider.read(..)  returns a single entity identified by key. The key property and the representation are been obtained by the EDM definition.</p>
-<h5 id="processor-implementation">Processor implementation</h5>
+<h5 id="processor-implementation">Processor implementation<a class="headerlink" href="#processor-implementation" title="Permanent link">&para;</a></h5>
 <p>The processor handles requests been sent to the server.  Each processor can handle different types of requests.  It is free to the user of library, if a single class implement all needed interfaces or if the implementation will be split in multiple classes. In this example we will implement a single class, which implements the processor interfaces <em>EntityCollectionProcessor</em>, <em>EntityProcessor</em>, <em>ComplexProcessor</em> and <em>PrimitiveProcessor</em>. The processors have to be registered in the Servlet (See chapter: Complete servlet implementation)</p>
 <p>The design of the processor interface is given by the different representations of a resource. Consider the e.g. URI “../service/EntityCollection”, so the ODataHandler will call a processor that implements the EntityCollectionProcessor interface.  In the other hand a request to "./service/EntityCollection(myKeyValue)” will be dispatched to a processor, that implements the EntityProcessor interface. Further information about the detailed processor design can be found in the Processor Interface documentation <a href="https://wiki.apache.org/Olingo/Documentation/ProcessorInterfaces">https://wiki.apache.org/Olingo/Documentation/ProcessorInterfaces</a> and in the corresponding Javadoc.</p>
 <p><strong>Helper methods:</strong></p>
@@ -789,7 +800,7 @@ After the implementation of the EDM Prov
 </pre></div>
 
 
-<h5 id="complete-servlet-implementation">Complete servlet implementation</h5>
+<h5 id="complete-servlet-implementation">Complete servlet implementation<a class="headerlink" href="#complete-servlet-implementation" title="Permanent link">&para;</a></h5>
 <p>Replace the <code>CarsServlet.service(..)</code> method with following snipped:</p>
 <div class="codehilite"><pre><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>
@@ -834,8 +845,8 @@ After the implementation of the EDM Prov
 <li>Primitive property:   <a href="http://localhost:8080/odata-server-sample/cars.svc/Cars(5)/Price">http://localhost:8080/odata-server-sample/cars.svc/Cars(5)/Price</a></li>
 <li>Complex property: <a href="http://localhost:8080/odata-server-sample/cars.svc/Manufacturers(1)/Address">http://localhost:8080/odata-server-sample/cars.svc/Manufacturers(1)/Address</a></li>
 </ul>
-<h3 id="basis-read-scenario">Basis read scenario</h3>
-<h5 id="setup-maven-project">Setup Maven project</h5>
+<h3 id="basis-read-scenario">Basis read scenario<a class="headerlink" href="#basis-read-scenario" title="Permanent link">&para;</a></h3>
+<h5 id="setup-maven-project">Setup Maven project<a class="headerlink" href="#setup-maven-project" title="Permanent link">&para;</a></h5>
 <p>As described in the previous tutorial, create a new Maven project.</p>
 <p>We will add the dependencies to the OData client library. To do so, replace the pom.xml by the following snipped.</p>
 <div class="codehilite"><pre><span class="nt">&lt;project</span> <span class="na">xmlns=</span><span class="s">&quot;http://maven.apache.org/POM/4.0.0&quot;</span> <span class="na">xmlns:xsi=</span><span class="s">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>
@@ -882,7 +893,7 @@ After the implementation of the EDM Prov
 </pre></div>
 
 
-<h5 id="implementation">Implementation</h5>
+<h5 id="implementation">Implementation<a class="headerlink" href="#implementation" title="Permanent link">&para;</a></h5>
 <p>The following class fetchs data from an OData service.</p>
 <p>To request some data the following steps have to be done:</p>
 <ul>

Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_write.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_write.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_basic_write.html Wed Jul  8 13:49:34 2015
@@ -86,9 +86,20 @@
 
 			</div><!--/.nav-collapse -->
         </div><!--/.container-fluid -->
-      </div><!-- Main component for a primary marketing message or call to action --><h1 id="write-scenario">Write Scenario</h1>
+      </div><!-- Main component for a primary marketing message or call to action --><style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h1 id="write-scenario">Write Scenario<a class="headerlink" href="#write-scenario" title="Permanent link">&para;</a></h1>
 <hr />
-<h3 id="how-to-guide-for-building-a-sample-odata-service-with-the-odata-40-library-for-java">How To Guide for building a Sample OData service with the OData 4.0 Library (for Java)</h3>
+<h3 id="how-to-guide-for-building-a-sample-odata-service-with-the-odata-40-library-for-java">How To Guide for building a Sample OData service with the OData 4.0 Library (for Java)<a class="headerlink" href="#how-to-guide-for-building-a-sample-odata-service-with-the-odata-40-library-for-java" title="Permanent link">&para;</a></h3>
 <p><strong>TBD</strong></p><div align="center">
 <p>Copyright © 2013-2015, The Apache Software Foundation<br>
 				                Apache Olingo, Olingo, Apache, the Apache feather, and

Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_quick_start_sample.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_quick_start_sample.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/od4_quick_start_sample.html Wed Jul  8 13:49:34 2015
@@ -86,12 +86,23 @@
 
 			</div><!--/.nav-collapse -->
         </div><!--/.container-fluid -->
-      </div><!-- Main component for a primary marketing message or call to action --><h1 id="a-quickstart-guide-with-our-odata-40-sample-service">A QuickStart Guide with our OData 4.0 Sample service</h1>
+      </div><!-- Main component for a primary marketing message or call to action --><style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h1 id="a-quickstart-guide-with-our-odata-40-sample-service">A QuickStart Guide with our OData 4.0 Sample service<a class="headerlink" href="#a-quickstart-guide-with-our-odata-40-sample-service" title="Permanent link">&para;</a></h1>
 <hr />
-<h3 id="overview">Overview</h3>
+<h3 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h3>
 <p>Olingo has prepared a very simple sample car service that can work as a starting point for implementing a custom OData service. This service consists of a very simple EDM with two entity sets that are cars and manufactures and a memory based data provider that is a simple hash map. Therefore the project implements a very basic single OData processor supporting a minimal readonly scenario.</p>
 <p>This sample can be deployed to any JEE compliant web application server (e.g. <a href="http://tomcat.apache.org">Tomcat</a>) and be used to get an overview on how to provide an OData V4 compliant webserver. </p>
-<h3 id="prerequisites">Prerequisites</h3>
+<h3 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">&para;</a></h3>
 <p>To run this sample you will need to perfom the following steps:</p>
 <ul>
 <li>Get any JEE compliant web application server (e.g. <a href="http://tomcat.apache.org">Tomcat</a>)</li>
@@ -99,9 +110,9 @@
 <li>Deploy the war file to your server</li>
 </ul>
 <p>You can now explore the service.</p>
-<h3 id="get-the-war-file-via-the-maven-repository">Get the war file via the maven repository</h3>
+<h3 id="get-the-war-file-via-the-maven-repository">Get the war file via the maven repository<a class="headerlink" href="#get-the-war-file-via-the-maven-repository" title="Permanent link">&para;</a></h3>
 <p>To get the war file via the maven repository you can simple look <a href="https://repository.apache.org/index.html#nexus-search;gav~org.apache.olingo~odata-server-sample~~~">here</a> and download the war file. </p>
-<h3 id="build-the-war-file-on-your-own">Build the war file on your own</h3>
+<h3 id="build-the-war-file-on-your-own">Build the war file on your own<a class="headerlink" href="#build-the-war-file-on-your-own" title="Permanent link">&para;</a></h3>
 <p>You can also build the war file yourself using maven. To do this please set up your project by cloning our git repository. You can find a how to <a href="/doc/odata4/maven.html">here</a></p>
 <p>After you have executed the maven goals "clean install" you can find the war file in the target folder under "olingo-odata4/samples/server/target".</p>
 <p>If you would like to debug the service you can do so by integrating the whole project into eclipse by following this <a href="/doc/odata4/eclipse.html">tutorial</a>.</p><div align="center">

Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/read/tutorial_read_mvn.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/read/tutorial_read_mvn.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/read/tutorial_read_mvn.html Wed Jul  8 13:49:34 2015
@@ -86,9 +86,20 @@
 
 			</div><!--/.nav-collapse -->
         </div><!--/.container-fluid -->
-      </div><!-- Main component for a primary marketing message or call to action --><h1 id="appendix-for-maven-users">Appendix for Maven users</h1>
+      </div><!-- Main component for a primary marketing message or call to action --><style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h1 id="appendix-for-maven-users">Appendix for Maven users<a class="headerlink" href="#appendix-for-maven-users" title="Permanent link">&para;</a></h1>
 <p>Prerequisites for this Appendix is an installed Maven (Version 3.x) and access to the <a href="www.maven.org">Maven Central Repository</a></p>
-<h3 id="initial-project-setup">Initial project setup</h3>
+<h3 id="initial-project-setup">Initial project setup<a class="headerlink" href="#initial-project-setup" title="Permanent link">&para;</a></h3>
 <p>To create a Maven project without Eclipse, execute the following command on command line:</p>
 <div class="codehilite"><pre><span class="n">mvn</span> <span class="n">archetype</span><span class="p">:</span><span class="n">generate</span> <span class="o">\</span>
   <span class="o">-</span><span class="n">DgroupId</span><span class="p">=</span><span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">olingo</span> <span class="o">\</span>
@@ -102,9 +113,9 @@
 Afterwards, use the goal <code>eclipse:eclipse</code> in order to make the project Eclipse-like.
 This allows to import the project into Eclipse using the default Eclipse-importer:
 <code>File-&gt;import-&gt;General-&gt;Existing projects into workspace</code></p>
-<h3 id="implementation-of-the-demo-service">Implementation of the Demo Service</h3>
+<h3 id="implementation-of-the-demo-service">Implementation of the Demo Service<a class="headerlink" href="#implementation-of-the-demo-service" title="Permanent link">&para;</a></h3>
 <p>To implement the Demo Service see section <a href="tutorial_read.html#4-implementation">4. Implementation</a> in the tutorial.</p>
-<h3 id="append-jetty-to-pom">Append Jetty to pom</h3>
+<h3 id="append-jetty-to-pom">Append Jetty to pom<a class="headerlink" href="#append-jetty-to-pom" title="Permanent link">&para;</a></h3>
 <p>To add support for run the Demo Service via Maven and the Jetty plugin add following part into the <code>pom.xml</code>:</p>
 <div class="codehilite"><pre><span class="nt">&lt;build&gt;</span>
   <span class="nt">&lt;finalName&gt;</span><span class="cp">${</span><span class="n">project</span><span class="o">.</span><span class="n">artifactId</span><span class="cp">}</span><span class="nt">&lt;/finalName&gt;</span>

Modified: websites/staging/olingo/trunk/content/doc/odata4/tutorials/readep/tutorial_readep.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/odata4/tutorials/readep/tutorial_readep.html (original)
+++ websites/staging/olingo/trunk/content/doc/odata4/tutorials/readep/tutorial_readep.html Wed Jul  8 13:49:34 2015
@@ -86,9 +86,20 @@
 
 			</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>
-<h2 id="part-2-read-scenario-continued">Part 2: Read scenario continued</h2>
-<h3 id="introduction">Introduction</h3>
+      </div><!-- Main component for a primary marketing message or call to action --><style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<h1 id="how-to-build-an-odata-service-with-olingo-v4">How to build an OData Service with Olingo V4<a class="headerlink" href="#how-to-build-an-odata-service-with-olingo-v4" title="Permanent link">&para;</a></h1>
+<h2 id="part-2-read-scenario-continued">Part 2: Read scenario continued<a class="headerlink" href="#part-2-read-scenario-continued" title="Permanent link">&para;</a></h2>
+<h3 id="introduction">Introduction<a class="headerlink" href="#introduction" title="Permanent link">&para;</a></h3>
 <p>In the first tutorial, we’ve learned how to build a very simple OData service.<br />
 That service exposes its metadata and allows reading a list of products.<br />
 It doesn’t support accessing the URL for a single product.<br />
@@ -127,13 +138,13 @@ The sample code shouldn't be reused for
 <li>Links</li>
 <li>Appendix: PrimitiveValueProcessor</li>
 </ol>
-<h1 id="1-prerequisites">1. Prerequisites</h1>
+<h1 id="1-prerequisites">1. Prerequisites<a class="headerlink" href="#1-prerequisites" title="Permanent link">&para;</a></h1>
 <p>Follow <a href="http://olingo.apache.org/doc/odata4/tutorials/read/tutorial_read.html">Tutorial Part 1: Read Entity Collection</a>, which also covers setting up the environment and running the service.</p>
-<h1 id="2-preparation">2. Preparation</h1>
+<h1 id="2-preparation">2. Preparation<a class="headerlink" href="#2-preparation" title="Permanent link">&para;</a></h1>
 <p>Follow the <a href="http://olingo.apache.org/doc/odata4/tutorials/read/tutorial_read.html">Tutorial Part 1: Read Entity Collection</a> or import the  <a href="http://olingo.apache.org/doc/odata4/tutorials/read/sample/DemoService_Tutorial_Read.zip">sample project</a> into your Eclipse workspace.<br />
 Afterwards do a <em>Deploy and run</em>: it should be working.<br />
 Before we start with the actual tutorial, we need to adapt the existing code to meet the requirements of the present tutorial.</p>
-<h2 id="21-create-a-new-data-class">2.1. Create a new data-class</h2>
+<h2 id="21-create-a-new-data-class">2.1. Create a new data-class<a class="headerlink" href="#21-create-a-new-data-class" title="Permanent link">&para;</a></h2>
 <p>In the first tutorial, we had created a single method called <code>getData()</code> to provide sample data for the list of products.
 Handling the sample data will get a bit more advanced from now on, so we move the code into a separate class.</p>
 <p>Create a new package <em>myservice.mynamespace.data</em><br />
@@ -248,7 +259,7 @@ Within this package, create a new class
 They are data-layer-agnostic; their parameters are objects from the OData world.<br />
 The implementation of these methods simply delegates the logic to the internal methods.  </p>
 <p>The <em>internal</em> methods do know about the names of tables or columns and these methods know how to e.g. find a single product.</p>
-<h2 id="22-adapt-the-servlet-class">2.2. Adapt the servlet class</h2>
+<h2 id="22-adapt-the-servlet-class">2.2. Adapt the servlet class<a class="headerlink" href="#22-adapt-the-servlet-class" title="Permanent link">&para;</a></h2>
 <p>The <code>Data-Storage</code> class will be instantiated in the <code>DemoServlet</code> class and attached to the HTTP-session.<br />
 This has the advantage that our final OData service can be tested and the sample data can be changed and the changes will remain active until the session is closed.</p>
 <p>Open the class <code>myservice.mynamespace.web.DemoServlet</code></p>
@@ -274,9 +285,9 @@ This has the advantage that our final OD
 
 <p>Note that we pass the instance of the <code>Storage</code> object to the constructor of our existing <code>DemoEntityCollectionProcessor</code>.</p>
 <p>So the next step is to adapt the <code>DemoEntityCollectionProcessor</code> class.</p>
-<h2 id="23-modify-the-demoentitycollectionprocessor">2.3. Modify the DemoEntityCollectionProcessor</h2>
+<h2 id="23-modify-the-demoentitycollectionprocessor">2.3. Modify the DemoEntityCollectionProcessor<a class="headerlink" href="#23-modify-the-demoentitycollectionprocessor" title="Permanent link">&para;</a></h2>
 <p>In the <code>DemoEntityCollectionProcessor</code> class that we created in the first tutorial, we have to make 3 changes:</p>
-<h3 id="231-create-constructor">2.3.1 Create Constructor</h3>
+<h3 id="231-create-constructor">2.3.1 Create Constructor<a class="headerlink" href="#231-create-constructor" title="Permanent link">&para;</a></h3>
 <p>We have to create a Constructor that takes the <code>Storage</code> instance and stores it as a member variable:</p>
 <div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">DemoEntityCollectionProcessor</span> <span class="kd">implements</span> <span class="n">EntityCollectionProcessor</span> <span class="o">{</span>
 
@@ -290,10 +301,10 @@ This has the advantage that our final OD
 </pre></div>
 
 
-<h3 id="232-delete-the-getdata-method">2.3.2. Delete the getData() method</h3>
+<h3 id="232-delete-the-getdata-method">2.3.2. Delete the getData() method<a class="headerlink" href="#232-delete-the-getdata-method" title="Permanent link">&para;</a></h3>
 <p>The code that we had written in this method has been moved to the <code>init()</code> method of the Storage class.
 So we can delete this <code>getData()</code> method.</p>
-<h3 id="233-adapt-the-usage-of-the-getdata-method">2.3.3. Adapt the usage of the getData() method</h3>
+<h3 id="233-adapt-the-usage-of-the-getdata-method">2.3.3. Adapt the usage of the getData() method<a class="headerlink" href="#233-adapt-the-usage-of-the-getdata-method" title="Permanent link">&para;</a></h3>
 <p>After deleting the <code>getData()</code> method, we get a compile error in the line where this method is used.
 We replace this method invocation with a call to our <code>Storage</code> object:</p>
 <div class="codehilite"><pre><span class="n">EntitySet</span> <span class="n">entitySet</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="na">readEntitySetData</span><span class="o">(</span><span class="n">edmEntitySet</span><span class="o">);</span>
@@ -317,7 +328,7 @@ We replace this method invocation with a
 </pre></div>
 
 
-<h2 id="24-create-utility-class">2.4. Create utility class</h2>
+<h2 id="24-create-utility-class">2.4. Create utility class<a class="headerlink" href="#24-create-utility-class" title="Permanent link">&para;</a></h2>
 <p>Furthermore, we create one more class, to  host a few helper methods.<br />
 Create package <code>myservice.mynamespace.util</code>
 Within this package, create a class <code>Util.java</code></p>
@@ -431,7 +442,7 @@ Within this package, create a class <cod
 
 <p>These helper methods are going to be used within the implementation of the Processor implementations.</p>
 <hr />
-<h1 id="3-implementation-of-read-single-entity">3. Implementation of Read Single Entity</h1>
+<h1 id="3-implementation-of-read-single-entity">3. Implementation of Read Single Entity<a class="headerlink" href="#3-implementation-of-read-single-entity" title="Permanent link">&para;</a></h1>
 <p>The user of our sample OData service is enabled to invoke the list of products via the following 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>
 </pre></div>
@@ -446,7 +457,7 @@ This is done via the following URL:</p>
 <p>From the above URL we can see that the user requests the product which has an ID with value 3<br />
 Whenever such a URL is requested, the Olingo library will delegate the request to an implementation of the Interface <code>EntityProcessor</code>.</p>
 <p>This means, we have to create a new Java class that implements the mentioned interface and we have to register it in the <code>DemoServlet</code> class (remember that all Processor-implementations have to be registered there).</p>
-<h2 id="31-implement-the-entityprocessor-interface">3.1. Implement the EntityProcessor interface</h2>
+<h2 id="31-implement-the-entityprocessor-interface">3.1. Implement the EntityProcessor interface<a class="headerlink" href="#31-implement-the-entityprocessor-interface" title="Permanent link">&para;</a></h2>
 <p>The interface <code>org.apache.olingo.server.api.processor.EntityProcessor</code> has 5 methods to implement:</p>
 <ul>
 <li>
@@ -587,7 +598,7 @@ The <code>ODataSerializer</code> object
 </pre></div>
 
 
-<h2 id="32-adapt-the-demoservlet-class">3.2. Adapt the DemoServlet class</h2>
+<h2 id="32-adapt-the-demoservlet-class">3.2. Adapt the DemoServlet class<a class="headerlink" href="#32-adapt-the-demoservlet-class" title="Permanent link">&para;</a></h2>
 <p>As we’ve learned in our first tutorial, the Processor implementations have to be registered on the <code>ODataHttpHandler</code> instance in the servlet class.
 Open the <code>DemoServlet</code> class and add the line that registers the <code>DemoEntityProcessor</code> instance:</p>
 <div class="codehilite"><pre><span class="c1">// create odata handler and configure it with EdmProvider and Processor</span>
@@ -600,7 +611,7 @@ Open the <code>DemoServlet</code> class
 </pre></div>
 
 
-<h2 id="33-run-the-service">3.3. Run the service</h2>
+<h2 id="33-run-the-service">3.3. Run the service<a class="headerlink" href="#33-run-the-service" title="Permanent link">&para;</a></h2>
 <p>We have provided the implementation for the <code>readEntity(...)</code>, we have registered the processor and in the preparation section, we’ve created the <code>Storage</code> class and the <code>Util</code> class.
 After building and deploying the project, we can invoke e.g. the following 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>
@@ -618,7 +629,7 @@ After building and deploying the project
 
 
 <hr />
-<h1 id="4-implementation-of-read-single-property">4. Implementation of Read Single Property</h1>
+<h1 id="4-implementation-of-read-single-property">4. Implementation of Read Single Property<a class="headerlink" href="#4-implementation-of-read-single-property" title="Permanent link">&para;</a></h1>
 <p>In the following section, We will add the capabilities to our service that allows the user to invoke e.g. the following 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>1<span class="p">)</span><span class="o">/</span><span class="n">Description</span>
 </pre></div>
@@ -647,7 +658,7 @@ Don’t mix the above mentioned call
 
 <p>Here, the response body contains only the pure value of the property, in plain text.
 This can be realized by implementing the interface <code>PropertyValueProcessor</code> (see Appendix)</p>
-<h2 id="41-implement-the-primitiveprocessor-interface">4.1. Implement the PrimitiveProcessor interface</h2>
+<h2 id="41-implement-the-primitiveprocessor-interface">4.1. Implement the PrimitiveProcessor interface<a class="headerlink" href="#41-implement-the-primitiveprocessor-interface" title="Permanent link">&para;</a></h2>
 <p>The interface <code>org.apache.olingo.server.api.processor.PrimitiveProcessor</code> has 4 methods to implement:</p>
 <ul>
 <li>
@@ -751,7 +762,7 @@ This can be realized by implementing the
 
 </li>
 </ol>
-<h2 id="42-adapt-the-demoservlet-class">4.2. Adapt the DemoServlet class</h2>
+<h2 id="42-adapt-the-demoservlet-class">4.2. Adapt the DemoServlet class<a class="headerlink" href="#42-adapt-the-demoservlet-class" title="Permanent link">&para;</a></h2>
 <p>The DemoServlet has to register a third processor:</p>
 <div class="codehilite"><pre><span class="c1">// create odata handler and configure it with EdmProvider and Processor</span>
 <span class="n">OData</span> <span class="n">odata</span> <span class="o">=</span> <span class="n">OData</span><span class="o">.</span><span class="na">newInstance</span><span class="o">();</span>
@@ -764,7 +775,7 @@ This can be realized by implementing the
 </pre></div>
 
 
-<h2 id="43-run-the-service">4.3. Run the service</h2>
+<h2 id="43-run-the-service">4.3. Run the service<a class="headerlink" href="#43-run-the-service" title="Permanent link">&para;</a></h2>
 <p>We have provided the implementation for the <code>readPrimitive</code>, we have registered the processor and in the preparation section, we’ve created the <code>Storage</code> class and the <code>Util</code> class.
 After building and deploying the project, we can invoke e.g. the following 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><span class="n">ID</span><span class="p">=</span>3<span class="p">)</span><span class="o">/</span><span class="n">Description</span>
@@ -786,12 +797,12 @@ After building and deploying the project
 
 
 <hr />
-<h1 id="5-summary">5. Summary</h1>
+<h1 id="5-summary">5. Summary<a class="headerlink" href="#5-summary" title="Permanent link">&para;</a></h1>
 <p>In this tutorial we have learned how to implement the read operation for single entity and single property.
 It has been based on a simple OData model, focusing on simple sample code and sample data.</p>
 <p>In the next tutorial (<a href="/doc/odata4/tutorials/write/tutorial_write.html">Part 3: Write</a>) we will learn how to implement write operations, i.e. create, update and delete of an entity.</p>
 <hr />
-<h1 id="6-links">6. Links</h1>
+<h1 id="6-links">6. Links<a class="headerlink" href="#6-links" title="Permanent link">&para;</a></h1>
 <ul>
 <li>Tutorial OData V4 service part 1: <a href="/doc/odata4/tutorials/read/tutorial_read.html">Read Entity Collection</a> | <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Read.zip">sample project</a> (<a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Read.zip.md5">md5</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Read.zip.sha512">sha512</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_Read.zip.asc">pgp</a>).</li>
 <li>Tutorial OData V4 service part 2: <a href="/doc/odata4/tutorials/readep/tutorial_readep.html">Read Entity, Read Property (this page)</a> | <a href="http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip">sample project zip</a> (<a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.md5">md5</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.sha512">sha512</a>, <a href="https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.asc">pgp</a>)  </li>



Mime
View raw message