You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2015/09/15 14:34:56 UTC

svn commit: r1703171 - in /olingo/site/trunk/content/doc/odata4/tutorials: sqo_es/tutorial_sqo_es.mdtext sqo_f/tutorial_sqo_f.mdtext sqo_o/tutorial_sqo_o.mdtext

Author: mibo
Date: Tue Sep 15 12:34:56 2015
New Revision: 1703171

URL: http://svn.apache.org/r1703171
Log:
Minor adaptions

Modified:
    olingo/site/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.mdtext
    olingo/site/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.mdtext
    olingo/site/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.mdtext

Modified: olingo/site/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.mdtext?rev=1703171&r1=1703170&r2=1703171&view=diff
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.mdtext (original)
+++ olingo/site/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.mdtext Tue Sep 15 12:34:56 2015
@@ -1,4 +1,4 @@
-Title:    Tutorial - Read service with Olingo V4
+Title:    Tutorial - System Query Options - Select and Expand
 Notice:    Licensed to the Apache Software Foundation (ASF) under one
            or more contributor license agreements.  See the NOTICE file
            distributed with this work for additional information
@@ -49,7 +49,7 @@ ___
 
 # 1. Prerequisites
 
-Same prerequisites as in [Tutorial Part 4: Navigation](http://olingo.apache.org/doc/odata4/tutorials/navigation/tutorial_navigation.html) as well as basic knowledge about the concepts presented there.
+Same prerequisites as in [Tutorial Part 4: Navigation](doc/odata4/tutorials/navigation/tutorial_navigation.html) as well as basic knowledge about the concepts presented there.
 
 Furthermore, basic knowledge about *System Query Options* (see [Tutorial Part 5.1](doc/odata4/tutorials/sqo_tcs/tutorial_sqo_tcs.html)) is helpful.
 
@@ -57,7 +57,7 @@ ___
 
 # 2. Preparation
 
-Follow [Tutorial Part 4: Navigation](http://olingo.apache.org/doc/odata4/tutorials/navigation/tutorial_navigation.html) or as shortcut import the [attached  project](http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip) into your Eclipse workspace.
+Follow [Tutorial Part 4: Navigation](doc/odata4/tutorials/navigation/tutorial_navigation.html) or as shortcut import the [attached  project](http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_Navigation.zip) into your Eclipse workspace.
 
 Afterwards do a _Deploy and run_: it should be working.
 
@@ -611,4 +611,4 @@ In this tutorial we have learned the bas
       response.setContent(serializerResult.getContent());
       response.setStatusCode(HttpStatusCode.OK.getStatusCode());
       response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
-    }
\ No newline at end of file
+    }

Modified: olingo/site/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.mdtext?rev=1703171&r1=1703170&r2=1703171&view=diff
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.mdtext (original)
+++ olingo/site/trunk/content/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.mdtext Tue Sep 15 12:34:56 2015
@@ -1,4 +1,4 @@
-Title:
+Title:    Tutorial - System Query Options - Filter
 Notice:    Licensed to the Apache Software Foundation (ASF) under one
            or more contributor license agreements.  See the NOTICE file
            distributed with this work for additional information
@@ -18,10 +18,7 @@ Notice:    Licensed to the Apache Softwa
 
 # How to build an OData Service with Olingo V4
 
-# Part 5.4: System Query Options: $filter	
-
-
-
+# Part 5.4: System Query Options: `$filter`
 
 ## Introduction
 
@@ -36,24 +33,24 @@ The full implementation of the OData ser
 
 **Table of Contents**
 
-  1.	Preparation
-  2.	Implementation
-    1.	Implement $filter 
-  3.	Run the implemented service
-  4.	Summary
-  5.	Links
+  1. Preparation
+  2. Implementation
+    1. Implement `$filter`
+  3. Run the implemented service
+  4. Summary
+  5. Links
 
 # 1. 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.
+Follow [Tutorial Part 1: Read Entity Collection](doc/odata4/tutorials/read/tutorial_read.html) and [Tutorial Part 2: Read Entity](doc/odata4/tutorials/readep/tutorial_readep.html) or as shortcut import the [sample project zip](http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip) ([md5](https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.md5), [sha512](https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.sha512), [pgp](https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_ReadEp.zip.asc)) attached to Tutorial Part 2 into your Eclipse workspace.
 
 Afterwards do a _Deploy and run_: it should be working.
 
 
-# 2. Implementation 
+# 2. Implementation
 
-The system query options we’re focusing on are applied to the entity collection only, therefore our 
-implementation for the $filter query options is done in the class
+The system query options we’re focusing on are applied to the entity collection only, therefore our
+implementation for the `$filter` query options is done in the class
 `myservice.mynamespace.service.DemoEntityCollectionProcessor`
 
 The general sequence is again:
@@ -64,13 +61,13 @@ The general sequence is again:
   4. Serialize
   5. Configure the response
 
-### 2.1 Implement $filter
+### 2.1 Implement `$filter`
 
 #### Background
 
 When requesting a list of entities from a service, the default behaviour is to return all entities on the list. The consumer of an OData service might want to be able to receive a subset by specifying certain criteria which each of the returned entities have to fulfill.  
 For example, a common use case would be to request all products with a specified minimum and maximum price.
-OData supports this requirement with the system query option **$filter**
+OData supports this requirement with the system query option `$filter`
 
 It is specified as follows:
 
@@ -82,7 +79,7 @@ See here for more details:
 [OData Version 4.0 Part 2: URL Conventions Plus Errata 02](http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398094)
 
 
-The expression given by the **$filter** query option has to return a Boolean value when applied to a certain entity on the entity list. Iff the value returned for a given entity is *“true”*, the service has to return the entity. Otherwise the service has to discard the entity.
+The expression given by the `$filter` query option has to return a Boolean value when applied to a certain entity on the entity list. If the value returned for a given entity is *“true”*, the service has to return the entity. Otherwise the service has to discard the entity.
 
 
 **Example**
@@ -96,7 +93,7 @@ First, just to remember how the full pay
 Now have a look to the following Uri:  
 [http://localhost:8080/DemoService/DemoService.svc/Products?$filter=ID eq 1 or contains(Description,'1280')]([http://localhost:8080/DemoService/DemoService.svc/Products?$filter=ID eq 1 or contains(Description,'1280'))
 
-The $filter system query option has been applied to the Products Entity Collection. The client requests all products which fulfills the following condition: ID equals to one or the Description should contain the string ‘1280’
+The `$filter` system query option has been applied to the Products Entity Collection. The client requests all products which fulfills the following condition: ID equals to one or the Description should contain the string ‘1280’
 
 ![ProductsWithFilter](filter_applied.png "Products with applied $filter")
 
@@ -104,11 +101,11 @@ The $filter system query option has been
 
 First things first, the Uri parser creates an *abstract syntax tree* (AST).  An abstract syntax tree describes the expression in a hierarchical way. (see figure 1) For example to calculate the root node, all nodes below have to be calculated first. The idea is to traverse the tree in pre order (depth-first).
 
-Consider the following Uri 
+Consider the following Uri
 
     “/Products?$format=(Price lt 2000) and contains(Description,’Notebook’)”.
 
-As you can see, the intention is to request all Products, which costs less than 2000 monetary units and contains the word ‘Notebook’ in their description. The expression is split up in two parts by the binary operator “and”.  To calculate the result of the “and” node, the left and also the right child have to be calculated first.  The left child itself is another binary operation. So to calculate “less than” the type and value of the property “Price” has to be determined.  And so on…
+As you can see, the intention is to request all Products, which costs less than 2000 monetary units and contains the word ‘Notebook’ in their description. The expression is split up in two parts by the binary operator “and”.  To calculate the result of the “and” node, the left and also the right child have to be calculated first. The left child itself is another binary operation. So to calculate “less than” the type and value of the property “Price” has to be determined. And so on...
 
 ![AbstractSyntaxTree](ast.png "Abstract syntax tree of the filter expression “Price lt 2000 and contains(Description,’Notebook’)")
 
@@ -127,33 +124,33 @@ Action
 6. Calculate – **contains**(“Notebook Basic…”, “Notebook”)    | Edm.Boolean   | true                | visitMethodCall
 7. Calculate – true **and** true                              | Edm.Boolean   | true                | visitBinaryOperator
 
-Olingo uses the vistor pattern to traverse the AST. Each of these actions is mapped to one method of the ExpressionVistor interface. You can see the name of the methods in last column of table 1. As service developers we have to implement this methods but we don`t have to take care about calling them. The libaray will call the proper method and we have only to calculate the result. 
+Olingo uses the vistor pattern to traverse the AST. Each of these actions is mapped to one method of the ExpressionVistor interface. You can see the name of the methods in last column of table 1. As service developers we have to implement this methods but we do not have to take care about calling them. The libaray will call the proper method and we have only to calculate the result.
 
 
 #### Implementation
 
-First we will create the *Filter Expression Visitor* and after that, we`ll integrate the just created Visitor in *EntityCollectionProcessor*.
+First we will create the *Filter Expression Visitor* and after that, we will integrate the just created Visitor in `EntityCollectionProcessor`.
 
 **1.1 Create our FilterExpressionVisitor**
 
-Create a new class *FilterExpressionVisitor* in package *myservice.mynamespace.service* and  
-implement the Interface *org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor*. 
+Create a new class `FilterExpressionVisitor` in package `myservice.mynamespace.service` and  
+implement the Interface `org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor`.
 
-As you mentioned the interface needs a generic parameter. 
-This generic type is used as (return) parameter for the visitXXX methods (e.g. *visitLiteral* ). It`s up to your implementation to
-choose a proper type for your use case. The main task is to keep track of the type and also the return value of a node in the abstract syntax tree. 
-In real world scenarios it is common to build a statement to query a database or backend instead modifying the preloaded data. 
+As you mentioned the interface needs a generic parameter.
+This generic type is used as (return) parameter for the visitXXX methods (e.g. `visitLiteral` ). It is up to your implementation to
+choose a proper type for your use case. The main task is to keep track of the type and also the return value of a node in the abstract syntax tree.
+In real world scenarios it is common to build a statement to query a database or backend instead modifying the preloaded data.
 
-In this tutorial we will use just *Object* and pass the native Java values around.
+In this tutorial we will use just `Object` and pass the native Java values around.
 
     ::::java
     public class FilterExpressionVisitor implements ExpressionVisitor<Object> {
 
-Please create also a constructor to pass an entity to our visitor implementation. 
+Please create also a constructor to pass an entity to our visitor implementation.
 
     ::::java
     private Entity currentEntity;
-    
+
     public FilterExpressionVisitor(Entity currentEntity) {
         this.currentEntity = currentEntity;
     }
@@ -161,20 +158,20 @@ Please create also a constructor to pass
 **1.2 Implement the interface**
 
 In this basic tutorial we will implement only a subset of the Expression Visitor.
-The following methods will **not** be implemented. Add an *ODataApplicationException* to their bodies
+The following methods will **not** be implemented. Add an `ODataApplicationException` to their bodies:
 
-  - public Object visitTypeLiteral(EdmType type)
-  - public Object visitAlias(String aliasName)
-  - public Object visitEnum(EdmEnumType type, List<String> enumValues)
-  - public Object visitLambdaExpression(String lambdaFunction, String lambdaVariable, Expression expression)
-  - public Object visitLambdaReference(String variableName)
+  - `public Object visitTypeLiteral(EdmType type)`
+  - `public Object visitAlias(String aliasName)`
+  - `public Object visitEnum(EdmEnumType type, List<String> enumValues)`
+  - `public Object visitLambdaExpression(String lambdaFunction, String lambdaVariable, Expression expression)`
+  - `public Object visitLambdaReference(String variableName)`
 
 **Example**
 
     ::::java
     @Override
     public Object visitTypeLiteral(EdmType type) throws ExpressionVisitException, ODataApplicationException {
-        throw new ODataApplicationException("Type literals are not implemented", 
+        throw new ODataApplicationException("Type literals are not implemented",
             			HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
     }
 
@@ -186,11 +183,11 @@ This method is been called if the curren
         // To keeps things simple, this tutorial allows only primitive properties.
         // We have faith that the java type of Edm.Int32 is Integer
         final List<UriResource> uriResourceParts = member.getUriResourceParts();
-        
-        // Make sure that the resource path of the property contains only a single segment and a 
+
+        // Make sure that the resource path of the property contains only a single segment and a
         // primitive property has been addressed. We can be sure, that the property exists because  
         // the UriParser checks if the property has been defined in service metadata document.
-        
+
         if(uriResourceParts.size() == 1 && uriResourceParts.get(0) instanceof UriResourcePrimitiveProperty) {
           UriResourcePrimitiveProperty uriResourceProperty = (UriResourcePrimitiveProperty) uriResourceParts.get(0);
           return currentEntity.getProperty(uriResourceProperty.getProperty().getName()).getValue();
@@ -198,11 +195,11 @@ This method is been called if the curren
           // The OData specification allows in addition complex properties and navigation    
           // properties with a target cardinality 0..1 or 1.
           // This means any combination can occur e.g. Supplier/Address/City
-          //  -> Navigation properties  Supplier 
+          //  -> Navigation properties  Supplier
           //  -> Complex Property       Address
           //  -> Primitive Property     City
           // For such cases the resource path returns a list of UriResourceParts
-          throw new ODataApplicationException("Only primitive properties are implemented in filter 
+          throw new ODataApplicationException("Only primitive properties are implemented in filter
               expressions", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
         }
     }
@@ -213,22 +210,22 @@ The next method takes a String and has t
 
 **Example**  
 
-  - "‘1’" is a string with the value "1"
-  - "1"   could be an Edm.Byte, Edm.SByte, Edm.Int16, Edm.Int32, Edm.Int64, Edm.Single, Edm.Double, Edm.Decimal with value 1
+  - "`‘1’`" is a string with the value "`1`"
+  - "`1`"   could be an Edm.Byte, Edm.SByte, Edm.Int16, Edm.Int32, Edm.Int64, Edm.Single, Edm.Double, Edm.Decimal with value 1
 
-As you can see in this little example, it can be difficult to guess the right type. In this tutorial we will focus on Edm.Int32. 
+As you can see in this little example, it can be difficult to guess the right type. In this tutorial we will focus on Edm.Int32.
 
 In real world scenarios, there is something called “numeric promotion”, which converts numbers to the next higher type. [OData Version 4.0 Part 2: URL Conventions Plus Errata 02](http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398161)
 
-  
+
     ::::java
     @Override
     public Object visitLiteral(Literal literal) throws ExpressionVisitException, ODataApplicationException {
         // To keep this tutorial simple, our filter expression visitor supports only Edm.Int32 and Edm.String
         // In real world scenarios it can be difficult to guess the type of an literal.
-        // We can be sure, that the literal is a valid OData literal because the URI Parser checks 
+        // We can be sure, that the literal is a valid OData literal because the URI Parser checks
         // the lexicographical structure
-        
+
         // String literals start and end with an single quotation mark
         String literalAsString = literal.getText();
         if(literal.getType() instanceof EdmString) {
@@ -236,14 +233,14 @@ In real world scenarios, there is someth
             if(literal.getText().length() > 2) {
                 stringLiteral = literalAsString.substring(1, literalAsString.length() - 1);
             }
-          
+
             return stringLiteral;
         } else {
             // Try to convert the literal into an Java Integer
             try {
                 return Integer.parseInt(literalAsString);
             } catch(NumberFormatException e) {
-                throw new ODataApplicationException("Only Edm.Int32 and Edm.String literals are implemented", 
+                throw new ODataApplicationException("Only Edm.Int32 and Edm.String literals are implemented",
                     HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
             }
         }
@@ -251,50 +248,50 @@ In real world scenarios, there is someth
 
 **Implement the operators**
 
-The first two implemented methods dealt on the leaves of the AST.  Now we will implement the operations, which can be performed on these values.
+The first two implemented methods dealt on the leaves of the AST. Now we will implement the operations, which can be performed on these values.
 
-The idea behind the implementation is always the same. 
+The idea behind the implementation is always the same.
 
- 1. Check if the types fit together
- 2. If true => Calculate and return the result
- 3. Otherwise => Throw an *ODataApplicationException* with StatusCode 400 Bad Request
+  1. Check if the types fit together
+  2. If true => Calculate and return the result
+  3. Otherwise => Throw an `ODataApplicationException` with StatusCode 400 Bad Request
 
-OData supports two different unary operators. First there is the binary negation (*not*) and second the arithmetic minus (*-*). 
+OData supports two different unary operators. First there is the binary negation (*not*) and second the arithmetic minus (*-*).
 
     ::::java
-    public Object visitUnaryOperator(UnaryOperatorKind operator, Object operand) 
+    public Object visitUnaryOperator(UnaryOperatorKind operator, Object operand)
           throws ExpressionVisitException, ODataApplicationException {
-        // OData allows two different unary operators. We have to take care, that the type of the 
+        // OData allows two different unary operators. We have to take care, that the type of the
         // operand fits to the operand
-        
+
         if(operator == UnaryOperatorKind.NOT && operand instanceof Boolean) {
-          // 1.) boolean negation 
+          // 1.) boolean negation
           return !(Boolean) operand;
         } else if(operator == UnaryOperatorKind.MINUS && operand instanceof Integer){
           // 2.) arithmetic minus
           return -(Integer) operand;
         }
-        
+
         // Operation not processed, throw an exception
-        throw new ODataApplicationException("Invalid type for unary operator", 
+        throw new ODataApplicationException("Invalid type for unary operator",
             HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
     }
 
 Next are the binary operations.  Have a look at the source code comments for a detailed explanation.´
-    
+
     ::::java
     @Override
     public Object visitBinaryOperator(BinaryOperatorKind operator, Object left, Object right)     
                 throws ExpressionVisitException, ODataApplicationException {
-    		
-        // Binary Operators are split up in three different kinds. Up to the kind of the 
+
+        // Binary Operators are split up in three different kinds. Up to the kind of the
         // operator it can be applied to different types
-        //   - Arithmetic operations like add, minus, modulo, etc. are allowed on numeric 
+        //   - Arithmetic operations like add, minus, modulo, etc. are allowed on numeric
         //     types like Edm.Int32
         //   - Logical operations are allowed on numeric types and also Edm.String
         //   - Boolean operations like and, or are allowed on Edm.Boolean
-        // A detailed explanation can be found in OData Version 4.0 Part 2: URL Conventions 
-    	  
+        // A detailed explanation can be found in OData Version 4.0 Part 2: URL Conventions
+
         if (operator == BinaryOperatorKind.ADD
             || operator == BinaryOperatorKind.MOD
             || operator == BinaryOperatorKind.MUL
@@ -312,19 +309,19 @@ Next are the binary operations.  Have a
             || operator == BinaryOperatorKind.OR) {
           return evaluateBooleanOperation(operator, left, right);
     	  } else {
-    	    throw new ODataApplicationException("Binary operation " + operator.name() + " is not 
+    	    throw new ODataApplicationException("Binary operation " + operator.name() + " is not
                  implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
     	  }
       }
-    
+
     private Object evaluateBooleanOperation(BinaryOperatorKind operator, Object left, Object right)
     	    throws ODataApplicationException {
-    	  
+
         // First check that both operands are of type Boolean
         if(left instanceof Boolean && right instanceof Boolean) {
            Boolean valueLeft = (Boolean) left;
     	   Boolean valueRight = (Boolean) right;
-    	    
+
     	   // Than calculate the result value
     	   if(operator == BinaryOperatorKind.AND) {
     	      return valueLeft && valueRight;
@@ -333,17 +330,17 @@ Next are the binary operations.  Have a
     	      return valueLeft || valueRight;
     	   }
         } else {
-           throw new ODataApplicationException("Boolean operations needs two numeric operands", 
+           throw new ODataApplicationException("Boolean operations needs two numeric operands",
                  HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
         }
-    } 
+    }
 
     private Object evaluateComparisonOperation(BinaryOperatorKind operator, Object left, Object right) throws ODataApplicationException {
-        
+
         // All types in our tutorial supports all logical operations, but we have to make sure that   
         // the types are equal
         if(left.getClass().equals(right.getClass())) {
-          // Luckily all used types String, Boolean and also Integer support the interface 
+          // Luckily all used types String, Boolean and also Integer support the interface
           // Comparable
           int result;
           if(left instanceof Integer) {
@@ -353,10 +350,10 @@ Next are the binary operations.  Have a
           } else if(left instanceof Boolean) {
             result = ((Comparable<Boolean>) (Boolean) left).compareTo((Boolean) right);
           } else {
-            throw new ODataApplicationException("Class " + left.getClass().getCanonicalName() + " not expected", 
+            throw new ODataApplicationException("Class " + left.getClass().getCanonicalName() + " not expected",
                 HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH);
           }
-                
+
           if (operator == BinaryOperatorKind.EQ) {
             return result == 0;
           } else if (operator == BinaryOperatorKind.NE) {
@@ -371,21 +368,21 @@ Next are the binary operations.  Have a
             // BinaryOperatorKind.LT
             return result < 0;
           }
-          
+
         } else {
-          throw new ODataApplicationException("Comparision needs two equal types", 
+          throw new ODataApplicationException("Comparision needs two equal types",
               HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
         }
     }
 
-    private Object evaluateArithmeticOperation(BinaryOperatorKind operator, Object left, 
+    private Object evaluateArithmeticOperation(BinaryOperatorKind operator, Object left,
           	Object right) throws ODataApplicationException {
-    
+
         // First check if the type of both operands is numerical
     	if(left instanceof Integer && right instanceof Integer) {
     	    Integer valueLeft = (Integer) left;
     	    Integer valueRight = (Integer) right;
-    	    
+
     	    // Than calculate the result value
     	    if(operator == BinaryOperatorKind.ADD) {
     	      return valueLeft + valueRight;
@@ -400,42 +397,43 @@ Next are the binary operations.  Have a
     	      return valueLeft % valueRight;
     	    }
     	  } else {
-    	      throw new ODataApplicationException("Arithmetic operations needs two numeric 
+    	      throw new ODataApplicationException("Arithmetic operations needs two numeric
      			operands", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
     	  }
     }
 
-The last method we have to implement is *visitMethodCall*. The principle is always the same, check the types and calculate the return value. As a developer you can be sure, that the number of parameters fits to the MethodKind but the types have to be checked by yourself. E.g. *contains* takes two Strings and return *Edm.Boolean* but 
+The last method we have to implement is `visitMethodCall`. The principle is always the same, check the types and calculate the return value. As a developer you can be sure, that the number of parameters fits to the MethodKind but the types have to be checked by yourself. E.g. *contains* takes two Strings and return *Edm.Boolean* but
+
+       $filter=contains(123,123)
 
-       $filter=contains(123,123) 
-would not lead to an error. It`s up to you to throw an exception.
+would not lead to an error. It is up to you to throw an exception.
 
     ::::java
     @Override
-    public Object visitMethodCall(MethodKind methodCall, List<Object> parameters) 
+    public Object visitMethodCall(MethodKind methodCall, List<Object> parameters)
     	    throws ExpressionVisitException, ODataApplicationException {
-        
+
         // To keep this tutorial small and simple, we implement only one method call
         // contains(String, String) -> Boolean
         if(methodCall == MethodKind.CONTAINS) {
           if(parameters.get(0) instanceof String && parameters.get(1) instanceof String) {
             String valueParam1 = (String) parameters.get(0);
             String valueParam2 = (String) parameters.get(1);
-            
+
             return valueParam1.contains(valueParam2);
           } else {
-            throw new ODataApplicationException("Contains needs two parametes of type Edm.String", 
+            throw new ODataApplicationException("Contains needs two parametes of type Edm.String",
                 HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
           }
         } else {
-          throw new ODataApplicationException("Method call " + methodCall + " not implemented", 
+          throw new ODataApplicationException("Method call " + methodCall + " not implemented",
               HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
         }
     }
 
 **2. EntityCollectionProcessor changes**
 
-The following section describes the simple approach to enable the EntityCollectionProcessor class and the readEntityCollection() method for $filter.
+The following section describes the simple approach to enable the EntityCollectionProcessor class and the readEntityCollection() method for `$filter`.
 
 Just like in the previous tutorials, the data is first fetched from the backend, then the system query option is applied.
 
@@ -446,12 +444,12 @@ Just like in the previous tutorials, the
 
 We will proceed according to these 4 steps:
 
-  1. Get the query option from the UriInfo. If null is returned then nothing has to be done. 
-  2. Get the expression from the query option 
+  1. Get the query option from the UriInfo. If null is returned then nothing has to be done.
+  2. Get the expression from the query option
   3. Instantiate our Expression Visitor and evaluate the result for each entity in the collection
   4. Modify the EntityCollection based on the result of the expression
 
-**2.1  Get the  FilterOption from the uriInfo**
+**2.1 Get the FilterOption from the uriInfo**
 
     FilterOption filterOption = uriInfo.getFilterOption();
     if(filterOption != null) {
@@ -461,43 +459,43 @@ We will proceed according to these 4 ste
     Expression filterExpression = filterOption.getExpression();
 
 **2.3 Loop over all entities in the collection and calculate the result of the expression for a given entity**
-   
+
     ::::java
     try {
       List<Entity> entityList = entityCollection.getEntities();
       Iterator<Entity> entityIterator = entityList.iterator();
-    			      
+
       // Evaluate the expression for each entity
-      // If the expression is evaluated to "true", keep the entity otherwise remove it from 
+      // If the expression is evaluated to "true", keep the entity otherwise remove it from
       // the entityList
       while (entityIterator.hasNext()) {
-        // To evaluate the the expression, create an instance of the Filter Expression 
+        // To evaluate the the expression, create an instance of the Filter Expression
         // Visitor and pass the current entity to the constructor
         Entity currentEntity = entityIterator.next();
         FilterExpressionVisitor expressionVisitor = new FilterExpressionVisitor(currentEntity);
-    			    	  
+
         // Evaluating the expression
         Object visitorResult = filterExpression.accept(expressionVisitor);
         …
 
 **2.4 Modify the collection**   
-    
+
     ::::java  
          // The result of the filter expression must be of type Edm.Boolean
          if(visitorResult instanceof Boolean) {
             if(!Boolean.TRUE.equals(visitorResult)) {
-              // The expression evaluated to false (or null), so we have to remove the 
+              // The expression evaluated to false (or null), so we have to remove the
               // currentEntity from entityList
     	      entityIterator.remove();
             }
          } else {
              throw new ODataApplicationException("A filter expression must evaulate to type Edm.Boolean", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
-         } 
+         }
       } // End while
     } catch (ExpressionVisitException e) {
        throw new ODataApplicationException("Exception in filter evaluation",
                      HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH);
-    } 
+    }
 
 ### 3. Run the implemented service
 
@@ -542,7 +540,7 @@ After building and deploying your servic
 
 ## Summary
 
-In this tutorial we have learned how to implement a simple service with $filter system query option. The very same Expression Visitor can be used to support advanced $orderby query options. The main difference is that, the Expression Visitor used by $orderby returns a (may be calculated) value of a primitive property instead a Boolean value.
+In this tutorial we have learned how to implement a simple service with `$filter` system query option. The very same Expression Visitor can be used to support advanced $orderby query options. The main difference is that, the Expression Visitor used by $orderby returns a (may be calculated) value of a primitive property instead a Boolean value.
 
 ## Links
 
@@ -560,4 +558,4 @@ In this tutorial we have learned how to
 
   * [Official OData Homepage](http://odata.org/)
   * [OData documentation](http://www.odata.org/documentation/)
-  * [Olingo Javadoc](/javadoc/odata4/index.html)
\ No newline at end of file
+  * [Olingo Javadoc](/javadoc/odata4/index.html)

Modified: olingo/site/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.mdtext?rev=1703171&r1=1703170&r2=1703171&view=diff
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.mdtext (original)
+++ olingo/site/trunk/content/doc/odata4/tutorials/sqo_o/tutorial_sqo_o.mdtext Tue Sep 15 12:34:56 2015
@@ -1,4 +1,4 @@
-Title:
+Title:    Tutorial - System Query Options - OrderBy
 Notice:    Licensed to the Apache Software Foundation (ASF) under one
            or more contributor license agreements.  See the NOTICE file
            distributed with this work for additional information
@@ -18,29 +18,27 @@ Notice:    Licensed to the Apache Softwa
 
 # How to build an OData Service with Olingo V4
 
-# Part 5.3: System Query Options: $orderby	
+# Part 5.3: System Query Options: `$orderby`
 
 ## Introduction
 
-
-In the present tutorial, we’ll continue implementing OData system query options, this time focusing on **$orderby**
-
+In the present tutorial, we will continue implementing OData system query options, this time focusing on `$orderby`
 
 **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 as it is, shouldn’t be reused for advanced scenarios.
+Again, in the present tutorial, we will focus only on the relevant implementation, in order to keep the code small and simple. The sample code as it is, shouldn’t be reused for advanced scenarios.
 
 **Table of Contents**
 
-    1.	Prerequisites
-    2.	Preparation
-    3.	Implementation
-             1.Implement $ordergy 
-    4.	Run the implemented service
-    5.	Summary
-    6.	Links
+  1.	Prerequisites
+  2.	Preparation
+  3.	Implementation
+    1. Implement `$orderby`
+  4.	Run the implemented service
+  5.	Summary
+  6.	Links
 
 __
 
@@ -58,33 +56,32 @@ Follow _Tutorial Part 1: Read Entity Col
 
 Afterwards do a _Deploy and run_: it should be working.
 
-# Implementation 
+# Implementation
 
-The system query options we’re focusing on are applied to the entity collection only, therefore our 
+The system query options we’re focusing on are applied to the entity collection only, therefore our
 implementation for all query options is done in the class
 *myservice.mynamespace.service.DemoEntityCollectionProcessor*
 
 The general sequence is again:
 
-1.	Analyze the URI
-2.	Fetch data from backend
-3.	Apply the system query option
-4.	Serialize
-5.	Configure the response
+  1.	Analyze the URI
+  2.	Fetch data from backend
+  3.	Apply the system query option
+  4.	Serialize
+  5.	Configure the response
 
-## 3.1. Implement $orderby	
+## 3.1. Implement `$orderby`
 
 **Background**
 
 When requesting a list of entities from a service, it is up to the service implementation to decide in which order they are presented. This can depend on the backend data source, anyways, it is undefined.
-But the consumer of an OData service might want to be able to specify the order, according to his needs. 
+But the consumer of an OData service might want to be able to specify the order, according to his needs.
 
 For example, a usual case would be that the list of entities is sorted as per default by its ID number, but for a user, the ID is not relevant and he would prefer a sorting e.g. by the name
-OData supports this requirement with the system query option **$orderby**
+OData supports this requirement with the system query option `$orderby`
 It is specified as follows:
 
-
-    $orderby=<propertyName> 
+    $orderby=<propertyName>
 
 The order can be ascending or descending:
 
@@ -99,12 +96,12 @@ See here for more details:
 
 
 **Note:**
-As of the OData specification, the $orderby system query option can be applied to multiple properties.
+As of the OData specification, the `$orderby` system query option can be applied to multiple properties.
 In that case, the value is specified as comma-separated list.
 
 **Example:**
 
-    http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name asc, Description desc
+    <http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name asc, Description desc>
 
 In this example, all the products are sorted by their name. Moreover, all products with the same name are sorted by their description in descending order.
 Another example could be that I want to display all my customers, they should be sorted by their country. Additionally, within each country, they should be sorted by their name
@@ -118,7 +115,7 @@ First, just to remember how the full pay
 
 ![AllProductsNotSorted](products_unsorted.png "All products not sorted")
 
-The following request specifies the sorting by the name. 
+The following request specifies the sorting by the name.
 The order is ascending, if not specified elsewise.
 
 [http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name](http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name)
@@ -152,14 +149,14 @@ We will proceed according to these 4 ste
 
     :::java
     List<OrderByItem> orderItemList = orderByOption.getOrders();
-    final OrderByItem orderByItem = orderItemList.get(0); 
+    final OrderByItem orderByItem = orderItemList.get(0);
 
 The instance of an OrderByOption can be asked for the list of its *OrderByItems*.
 Why a list?
-Because the $orderby expression can be composed with multiple properties
+Because the `$orderby` expression can be composed with multiple properties
 For example, for the following URL, we get 2 OrderByItems:
 
-    http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name asc, Description desc 
+    http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name asc, Description desc
 
 In our example, we support only one property, therefore we directly access the first OrderByItem in the list.
 
@@ -214,18 +211,18 @@ So we have to retrieve that information
 The full implementation of the readEntityCollection() method:
 
     :::java
-    public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) 
+    public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
          throws ODataApplicationException, SerializerException {
-    
-    	// 1st retrieve the requested EntitySet from the uriInfo 
+
+    	// 1st retrieve the requested EntitySet from the uriInfo
     	List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
-    	UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); 
+    	UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
     	EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
-    
-    	// 2nd: fetch the data from backend 
+
+    	// 2nd: fetch the data from backend
     	EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet);
     	List<Entity> entityList = entityCollection.getEntities();
-    		
+
     	// 3rd apply $orderby
     	OrderByOption orderByOption = uriInfo.getOrderByOption();
     	if (orderByOption != null) {
@@ -238,50 +235,50 @@ The full implementation of the readEntit
     			if (uriResource instanceof UriResourcePrimitiveProperty) {
     				EdmProperty edmProperty = ((UriResourcePrimitiveProperty)uriResource).getProperty();
     				final String sortPropertyName = edmProperty.getName();
-    
+
     				// do the sorting for the list of entities  
     				Collections.sort(entityList, new Comparator<Entity>() {
-    
+
     					// delegate the sorting to native sorter of Integer and String
     					public int compare(Entity entity1, Entity entity2) {
     						int compareResult = 0;
-    
+
     						if(sortPropertyName.equals("ID")){
     							Integer integer1 = (Integer) entity1.getProperty(sortPropertyName).getValue();
     							Integer integer2 = (Integer) entity2.getProperty(sortPropertyName).getValue();
-    								
+
     							compareResult = integer1.compareTo(integer2);
     						}else{
     							String propertyValue1 = (String) entity1.getProperty(sortPropertyName).getValue();
     							String propertyValue2 = (String) entity2.getProperty(sortPropertyName).getValue();
-    								
+
     							compareResult = propertyValue1.compareTo(propertyValue2);
     						}
-    
-    						// if 'desc' is specified in the URI, change the order 
+
+    						// if 'desc' is specified in the URI, change the order
     						if(orderByItem.isDescending()){
-    							return - compareResult; // just reverse order 
+    							return - compareResult; // just reverse order
     						}
-    							
+
     						return compareResult;
     					}
     				});
     			}
     		}
     	}
-    		
-    		
+
+
     	// 4th: create a serializer based on the requested format (json)
     	ODataSerializer serializer = odata.createSerializer(responseFormat);
-    
+
     	// and serialize the content: transform from the EntitySet object to InputStream
     	EdmEntityType edmEntityType = edmEntitySet.getEntityType();
     	ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
-    
+
     	EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).build();
     	SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entityCollection, opts);
     	InputStream serializedContent = serializerResult.getContent();
-    
+
     	// 5th: configure the response object: set the body, headers and status code
     	response.setContent(serializedContent);
     	response.setStatusCode(HttpStatusCode.OK.getStatusCode());
@@ -294,14 +291,14 @@ After building and deploying your servic
 
   - The “normal” payload without query option  [http://localhost:8080/DemoService/DemoService.svc/Products](http://localhost:8080/DemoService/DemoService.svc/Products)
   - Sort by Name ascending   [http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name](http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name)
-  - Sort by Name descending   [http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name desc](http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name desc)
+  - Sort by Name descending [http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name desc](http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Name desc)
   - Sort by Description ascending  [http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description](http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description)
-  - Sort by Description descending  [http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description desc](http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description desc)
+  - Sort by Description descending [http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description desc](http://localhost:8080/DemoService/DemoService.svc/Products?$orderby=Description desc)
 
 # 5. Summary
 
-In this tutorial we have learned how to implement a simple $orderby 
-We’ve decided to not go for the advanced way of implementing $orderby, which would have been using an ExpressionVisitor, because that is treated in the $filter implementation.
+In this tutorial we have learned how to implement a simple `$orderby`.
+We have decided to not go for the advanced way of implementing `$orderby`, which would have been using an ExpressionVisitor, because that is treated in the `$filter` implementation.
 
 
 # 6. Links
@@ -317,5 +314,8 @@ We’ve decided to not go for the adv
   * Tutorial OData V4 service, part 5.4: [System Query Options $filter](/doc/odata4/tutorials/sqo_f/tutorial_sqo_f.html)
 
 
-OData specification: [http://odata.org/](http://odata.org/)   
-Olingo Javadoc: [http://olingo.apache.org/javadoc/odata4/index.html](http://olingo.apache.org/javadoc/odata4/index.html)
+### Further reading
+
+  * [Official OData Homepage](http://odata.org/)
+  * [OData documentation](http://www.odata.org/documentation/)
+  * [Olingo Javadoc](/javadoc/odata4/index.html)