Wednesday 24 July 2019

OData: Olingo: Read specific property of an entity


In my previous post, I explained how to read an entity separately. In this post, I am going to explain how to read specific property of an entity.

{SERVER_url}/DemoService.svc/Products(1)/Description : Give you the description of the product 1
{SERVER_url}/DemoService.svc/Products(1)/Price : Give you the price of the product 1

To get the property of each entity, we need to implement PrimitiveProcessor interface and register it with our OData handler.

PrimitiveProcess interface declare methods to retrieve, update and delete the value of specific property.

Below snippet receives the request and return the value associated with the property.
 public void readPrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
   throws ODataApplicationException, ODataLibraryException {

  List<UriResource> resourceParts = uriInfo.getUriResourceParts();

  UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0);
  EdmEntitySet edmEntitySet = uriEntityset.getEntitySet();

  List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();

  // Retrieve the requested (Edm) property. The last segment is the
  // Property
  UriResourceProperty uriProperty = (UriResourceProperty) resourceParts.get(resourceParts.size() - 1);
  EdmProperty edmProperty = uriProperty.getProperty();

  String edmPropertyName = edmProperty.getName();
  EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType();

  Entity entity = EntityUtil.readEntityData(edmEntitySet, keyPredicates);
  if (entity == null) { 
   throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(),
     Locale.ENGLISH);
  }

  Property property = entity.getProperty(edmPropertyName);
  if (property == null) {
   throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(),
     Locale.ENGLISH);
  }

  Object value = property.getValue();

  if (value == null) {
   response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
   return;
  }

  ODataSerializer serializer = odata.createSerializer(responseFormat);

  ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
  PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();

  SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
  InputStream propertyStream = serializerResult.getContent();

  response.setContent(propertyStream);
  response.setStatusCode(HttpStatusCode.OK.getStatusCode());
  response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());

 }

As compared to previous post, I added one class ‘DemoEdmPrimitiveProcessor.java’ and updated DemoServlet.


DemoEdmPrimitiveProcessor.java
package com.app.service;

import java.io.InputStream;
import java.util.List;
import java.util.Locale;

import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceProperty;

import com.app.util.EntityUtil;

public class DemoEdmPrimitiveProcessor implements PrimitiveProcessor {

 private OData odata;
 private ServiceMetadata serviceMetadata;

 @Override
 public void init(OData odata, ServiceMetadata serviceMetadata) {
  this.odata = odata;
  this.serviceMetadata = serviceMetadata;
 }

 @Override
 public void readPrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
   throws ODataApplicationException, ODataLibraryException {

  List<UriResource> resourceParts = uriInfo.getUriResourceParts();

  UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0);
  EdmEntitySet edmEntitySet = uriEntityset.getEntitySet();

  List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();

  // Retrieve the requested (Edm) property. The last segment is the
  // Property
  UriResourceProperty uriProperty = (UriResourceProperty) resourceParts.get(resourceParts.size() - 1);
  EdmProperty edmProperty = uriProperty.getProperty();

  String edmPropertyName = edmProperty.getName();
  EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType();

  Entity entity = EntityUtil.readEntityData(edmEntitySet, keyPredicates);
  if (entity == null) { 
   throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(),
     Locale.ENGLISH);
  }

  Property property = entity.getProperty(edmPropertyName);
  if (property == null) {
   throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(),
     Locale.ENGLISH);
  }

  Object value = property.getValue();

  if (value == null) {
   response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
   return;
  }

  ODataSerializer serializer = odata.createSerializer(responseFormat);

  ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
  PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();

  SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
  InputStream propertyStream = serializerResult.getContent();

  response.setContent(propertyStream);
  response.setStatusCode(HttpStatusCode.OK.getStatusCode());
  response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());

 }

 @Override
 public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo,
   ContentType requestFormat, ContentType responseFormat)
   throws ODataApplicationException, ODataLibraryException {
  // TODO Auto-generated method stub

 }

 @Override
 public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo)
   throws ODataApplicationException, ODataLibraryException {
  // TODO Auto-generated method stub

 }

}


DemoServlet.java
package com.app.servlet;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.app.service.DemoEdmPrimitiveProcessor;
import com.app.service.DemoEdmProvider;
import com.app.service.DemoEntityCollectionProcessor;
import com.app.service.DemoEntityProcessor;

public class DemoServlet extends HttpServlet {

 private static final long serialVersionUID = 1L;
 private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class);

 @Override
 protected void service(final HttpServletRequest req, final HttpServletResponse resp)
   throws ServletException, IOException {

  try {
   OData odata = OData.newInstance();
   
   ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList<EdmxReference>());
   
   ODataHttpHandler handler = odata.createHandler(edm);
   handler.register(new DemoEntityCollectionProcessor());
   handler.register(new DemoEntityProcessor());
   handler.register(new DemoEdmPrimitiveProcessor());
   
   handler.process(req, resp);

  } catch (RuntimeException e) {
   LOG.error("Server Error occurred in ExampleServlet", e);
   throw new ServletException(e);
  }
 }
}

Run the application on server and hit the url.
http://localhost:8080/olingoReadData/DemoService.svc/Products(1)/Description


You will receive below data.
<?xml version="1.0" encoding="UTF-8"?>
<m:value xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" m:context="$metadata#Products/Description">Good for morth east countries</m:value>


http://localhost:8080/olingoReadData/DemoService.svc/Products(1)/Price

You will receive below data.
<?xml version="1.0" encoding="UTF-8"?>
<m:value xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" m:context="$metadata#Products/Price" m:type="Double">876544.0</m:value>


http://localhost:8080/olingoReadData/DemoService.svc/Products(1)/vendor

You will receive below data.

<?xml version="1.0" encoding="UTF-8"?>
<error xmlns="http://docs.oasis-open.org/odata/ns/metadata">
   <code>404</code>
   <message>The type 'OData.Demo.Product' has no property 'vendor'.</message>
</error>


Previous                                                    Next                                                    Home

No comments:

Post a Comment