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());
+ }