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/08/12 09:21:17 UTC

svn commit: r1695432 - /olingo/site/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.mdtext

Author: mibo
Date: Wed Aug 12 07:21:17 2015
New Revision: 1695432

URL: http://svn.apache.org/r1695432
Log:
Added =* part

Modified:
    olingo/site/trunk/content/doc/odata4/tutorials/sqo_es/tutorial_sqo_es.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=1695432&r1=1695431&r2=1695432&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 Wed Aug 12 07:21:17 2015
@@ -128,12 +128,12 @@ In this tutorial we use the simple imple
 
         :::java
         // we need the property names of the $select, in order to build the context URL
-        String selectList = odata.createUriHelper().buildContextURLSelectList(
-        edmEntityType, null, selectOption);
+        String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType,
+                                                                              null, selectOption);
         ContextURL contextUrl = ContextURL.with()
-                  .entitySet(edmEntitySet)
-                  .selectList(selectList)
-                  .build();
+                                          .entitySet(edmEntitySet)
+                                          .selectList(selectList)
+                                          .build();
 
 
   * Furthermore, the serializer has to know about the usage of `$select`.
@@ -141,9 +141,9 @@ In this tutorial we use the simple imple
 
         :::java
         EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with()
-                  .contextURL(contextUrl)
-                  .select(selectOption)
-                  .build();
+                                                                                  .contextURL(contextUrl)
+                                                                                  .select(selectOption)
+                                                                                  .build();
 
 
 
@@ -152,7 +152,7 @@ In this tutorial we use the simple imple
     :::java
     public void readEntityCollection(ODataRequest request, ODataResponse response,
                         UriInfo uriInfo, ContentType responseFormat)
-                        throws ODataApplicationException, SerializerException {
+                          throws ODataApplicationException, SerializerException {
 
       // 1st retrieve the requested EdmEntitySet from the uriInfo
       List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
@@ -174,21 +174,21 @@ In this tutorial we use the simple imple
       // and serialize the content: transform from the EntitySet object to InputStream
       EdmEntityType edmEntityType = edmEntitySet.getEntityType();
       // we need the property names of the $select, in order to build the context URL
-      String selectList = odata.createUriHelper().buildContextURLSelectList(
-                        edmEntityType, null, selectOption);
+      String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType,
+                                                                            null, selectOption);
       ContextURL contextUrl = ContextURL.with()
-            .entitySet(edmEntitySet)
-            .selectList(selectList)
-            .build();
+                                        .entitySet(edmEntitySet)
+                                        .selectList(selectList)
+                                        .build();
 
 
       // adding the selectOption to the serializerOpts will tell the lib to do the job
       EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with()
-            .contextURL(contextUrl)
-            .select(selectOption)
-            .build();
-      SerializerResult serializerResult = serializer.entityCollection(srvMetadata,
-                        edmEntityType, entityCollection, opts);
+                                                                                .contextURL(contextUrl)
+                                                                                .select(selectOption)
+                                                                                .build();
+      SerializerResult serializerResult = serializer.entityCollection(srvMetadata, edmEntityType,
+                                                                          entityCollection, opts);
 
       // 5th: configure the response object: set the body, headers and status code
       response.setContent(serializerResult.getContent());
@@ -293,23 +293,56 @@ Most OData services will have more entit
 Such `$expand` expression is not considered in our example.  
 
 
-Now that we have the `ExpandItem`, the next step is to extract the navigation property from it.  
-For that, we have to ask the ExpandItem for its list if resource segments.  
+Now that we have the `ExpandItem`, the next step is to extract the navigation property (`EdmNavicationProperty`) from it.  
+
+For the case of a request with `$expand=*` (to expand all navigation items which is checked via `expandItem.isStar()`), all known `EdmNavigationPropertyBinding`s from the expanded `EdmEntityType` have to be checked.
+For our (reduced) sample service we know that only one navigation exists, hence the implementation is:
+
+    :::java
+    if(expandItem.isStar()) {
+      List<EdmNavigationPropertyBinding> bindings = edmEntitySet.getNavigationPropertyBindings();
+      // we know that there are navigation bindings
+      // however normally in this case a check if navigation bindings exists is done
+      if(!bindings.isEmpty()) {
+        // can in our case only be 'Category' or 'Products', so we can take the first
+        EdmNavigationPropertyBinding binding = bindings.get(0);
+        EdmElement property = edmEntitySet.getEntityType().getProperty(binding.getPath());
+        // we don't need to handle error cases, as it is done in the Olingo library
+        if(property instanceof EdmNavigationProperty) {
+          edmNavigationProperty = (EdmNavigationProperty) property;
+        }
+      }
+    } else {
+    ...
+
+
+For the case of a request with defined name of navigation property to expand (e.g. `$expand=Category`), we have to ask the ExpandItem for its list if resource segments.  
 The reason why an ExpandItem can be formed by multiple segments is that a navigation property can be in a `ComplexType`, such that it would be required to address it by a path.  
 
 In our simple example, we don’t need to specify a path, therefore we can safely write  
 
     :::java
-    UriResource uriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
+    ...
+    } else {
+      // can be 'Category' or 'Products', no path supported
+      UriResource uriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
+      // we don't need to handle error cases, as it is done in the Olingo library
+      if(uriResource instanceof UriResourceNavigation) {
+        edmNavigationProperty = ((UriResourceNavigation) uriResource).getProperty();
+      }
+    }
 
 This `uriResource` corresponds to the navigation property that we want to extract.  
 We expect that the `uriResource` is of type `UriResourceNavigation`, such that we can cast.  
-The `UriResourceNavigation` can then be asked for the `NavigationProperty` which in turn delivers the corresponding `EdmEntityType`, which we’re interested in:  
+The `UriResourceNavigation` can then be asked for the `NavigationProperty` which in turn delivers the corresponding `EdmEntityType`, which we’re interested in.
+
+Finally after one of above cases we have the necessary `EdmNavigationProperty` from which we need the `EdmEntityType` and the `name` of the navigation property to build the resopnse data.
 
     :::java
-    if(uriResource instanceof UriResourceNavigation){
-    EdmNavigationProperty edmNavigationProperty = ((UriResourceNavigation)uriResource).getProperty();
-    EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
+    if(edmNavigationProperty != null) {
+      EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
+      String navPropName = edmNavigationProperty.getName();
+      ...
 
 
 ##### Step 3: Build the response data
@@ -366,6 +399,10 @@ Also, the `expandOption` has to be consi
                                                           .expand(expandOption)
                                                           .build();
 
+
+**Note:**  
+The complete `readEntity(...)` method can be found in the *Appendix* at the end of the site or together with the `readEntityCollection(...)` method in the [sample project zip](http://www.apache.org/dyn/closer.cgi/olingo/odata4/Tutorials/DemoService_Tutorial_sqo_es.zip) ([md5](https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_sqo_es.zip.md5), [sha512](https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_sqo_es.zip.sha512), [pgp](https://dist.apache.org/repos/dist/release/olingo/odata4/Tutorials/DemoService_Tutorial_sqo_es.zip.asc)).
+
 ## 3.3. Implement $expand with options
 
 **Background**
@@ -459,3 +496,116 @@ In this tutorial we have learned the bas
   * [Official OData Homepage](http://odata.org/)
   * [OData documentation](http://www.odata.org/documentation/)
   * [Olingo Javadoc](/javadoc/odata4/index.html)
+
+# 7. Appendix
+
+### Sample code snippets
+
+**readEntity(...)**
+
+    :::java
+    public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
+            throws ODataApplicationException, SerializerException {
+
+      // 1. retrieve the Entity Type
+      List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+      // Note: only in our example we can assume that the first segment is the EntitySet
+      UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
+      EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+      // 2. retrieve the data from backend
+      List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+      Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
+
+      // 3. apply system query options
+
+      // handle $select
+      SelectOption selectOption = uriInfo.getSelectOption();
+      // in our example, we don't have performance issues, so we can rely upon the handling in the Olingo lib
+      // nothing else to be done
+
+      // handle $expand
+      ExpandOption expandOption = uriInfo.getExpandOption();
+      // in our example: http://localhost:8080/DemoService/DemoService.svc/Categories(1)/$expand=Products
+      // or http://localhost:8080/DemoService/DemoService.svc/Products(1)?$expand=Category
+      if(expandOption != null) {
+        // retrieve the EdmNavigationProperty from the expand expression
+        // Note: in our example, we have only one NavigationProperty, so we can directly access it
+        EdmNavigationProperty edmNavigationProperty = null;
+        ExpandItem expandItem = expandOption.getExpandItems().get(0);
+        if(expandItem.isStar()) {
+          List<EdmNavigationPropertyBinding> bindings = edmEntitySet.getNavigationPropertyBindings();
+          // we know that there are navigation bindings
+          // however normally in this case a check if navigation bindings exists is done
+          if(!bindings.isEmpty()) {
+            // can in our case only be 'Category' or 'Products', so we can take the first
+            EdmNavigationPropertyBinding binding = bindings.get(0);
+            EdmElement property = edmEntitySet.getEntityType().getProperty(binding.getPath());
+            // we don't need to handle error cases, as it is done in the Olingo library
+            if(property instanceof EdmNavigationProperty) {
+              edmNavigationProperty = (EdmNavigationProperty) property;
+            }
+          }
+        } else {
+          // can be 'Category' or 'Products', no path supported
+          UriResource uriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
+          // we don't need to handle error cases, as it is done in the Olingo library
+          if(uriResource instanceof UriResourceNavigation) {
+            edmNavigationProperty = ((UriResourceNavigation) uriResource).getProperty();
+          }
+        }
+
+        // can be 'Category' or 'Products', no path supported
+        // we don't need to handle error cases, as it is done in the Olingo library
+        if(edmNavigationProperty != null) {
+          EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
+          String navPropName = edmNavigationProperty.getName();
+
+          // build the inline data
+          Link link = new Link();
+          link.setTitle(navPropName);
+          link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
+
+          if(edmNavigationProperty.isCollection()){ // in case of Categories(1)/$expand=Products
+            // fetch the data for the $expand (to-many navigation) from backend
+            // here we get the data for the expand
+            EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(entity, expandEdmEntityType);
+            link.setInlineEntitySet(expandEntityCollection);
+          } else {  // in case of Products(1)?$expand=Category
+            // fetch the data for the $expand (to-one navigation) from backend
+            // here we get the data for the expand
+            Entity expandEntity = storage.getRelatedEntity(entity, expandEdmEntityType);
+            link.setInlineEntity(expandEntity);
+          }
+
+          // set the link - containing the expanded data - to the current entity
+          entity.getNavigationLinks().add(link);
+        }
+      }
+
+
+      // 4. serialize
+      EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+      // we need the property names of the $select, in order to build the context URL
+      String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType, expandOption, selectOption);
+      ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet)
+                                                .selectList(selectList)
+                                                .suffix(Suffix.ENTITY)
+                                                .build();
+
+      // make sure that $expand and $select are considered by the serializer
+      // adding the selectOption to the serializerOpts will actually tell the lib to do the job
+      EntitySerializerOptions opts = EntitySerializerOptions.with()
+                                                            .contextURL(contextUrl)
+                                                            .select(selectOption)
+                                                            .expand(expandOption)
+                                                            .build();
+
+      ODataSerializer serializer = this.odata.createSerializer(ODataFormat.fromContentType(responseFormat));
+      SerializerResult serializerResult = serializer.entity(srvMetadata, edmEntityType, entity, opts);
+
+      // 5. configure the response object
+      response.setContent(serializerResult.getContent());
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+    }