[OLINGO-713] Tutorial: Merged version of the tutorials added
This commit is contained in:
parent
170d561c04
commit
1558273f52
|
@ -20,6 +20,7 @@ package myservice.mynamespace.data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import myservice.mynamespace.service.DemoEdmProvider;
|
import myservice.mynamespace.service.DemoEdmProvider;
|
||||||
import myservice.mynamespace.util.Util;
|
import myservice.mynamespace.util.Util;
|
||||||
|
@ -30,7 +31,11 @@ import org.apache.olingo.commons.api.data.Property;
|
||||||
import org.apache.olingo.commons.api.data.ValueType;
|
import org.apache.olingo.commons.api.data.ValueType;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
|
||||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
import org.apache.olingo.server.api.uri.UriParameter;
|
import org.apache.olingo.server.api.uri.UriParameter;
|
||||||
|
|
||||||
public class Storage {
|
public class Storage {
|
||||||
|
@ -132,7 +137,44 @@ public class Storage {
|
||||||
|
|
||||||
return navigationTargetEntityCollection;
|
return navigationTargetEntityCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Entity createEntityData(EdmEntitySet edmEntitySet, Entity entityToCreate) {
|
||||||
|
|
||||||
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
|
// actually, this is only required if we have more than one Entity Type
|
||||||
|
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
|
||||||
|
return createProduct(edmEntityType, entityToCreate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is invoked for PATCH or PUT requests
|
||||||
|
* */
|
||||||
|
public void updateEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams, Entity updateEntity,
|
||||||
|
HttpMethod httpMethod) throws ODataApplicationException {
|
||||||
|
|
||||||
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
|
// actually, this is only required if we have more than one Entity Type
|
||||||
|
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
|
||||||
|
updateProduct(edmEntityType, keyParams, updateEntity, httpMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams)
|
||||||
|
throws ODataApplicationException {
|
||||||
|
|
||||||
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
|
// actually, this is only required if we have more than one Entity Type
|
||||||
|
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
|
||||||
|
deleteProduct(edmEntityType, keyParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* INTERNAL */
|
/* INTERNAL */
|
||||||
|
|
||||||
private EntityCollection getProducts() {
|
private EntityCollection getProducts() {
|
||||||
|
@ -172,9 +214,104 @@ public class Storage {
|
||||||
/* generic approach to find the requested entity */
|
/* generic approach to find the requested entity */
|
||||||
return Util.findEntity(edmEntityType, entitySet, keyParams);
|
return Util.findEntity(edmEntityType, entitySet, keyParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams, Entity entity,
|
||||||
|
HttpMethod httpMethod) throws ODataApplicationException {
|
||||||
|
|
||||||
|
Entity productEntity = getProduct(edmEntityType, keyParams);
|
||||||
|
if (productEntity == null) {
|
||||||
|
throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop over all properties and replace the values with the values of the given payload
|
||||||
|
// Note: ignoring ComplexType, as we don't have it in our odata model
|
||||||
|
List<Property> existingProperties = productEntity.getProperties();
|
||||||
|
for (Property existingProp : existingProperties) {
|
||||||
|
String propName = existingProp.getName();
|
||||||
|
|
||||||
|
// ignore the key properties, they aren't updateable
|
||||||
|
if (isKey(edmEntityType, propName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Property updateProperty = entity.getProperty(propName);
|
||||||
|
// the request payload might not consider ALL properties, so it can be null
|
||||||
|
if (updateProperty == null) {
|
||||||
|
// if a property has NOT been added to the request payload
|
||||||
|
// depending on the HttpMethod, our behavior is different
|
||||||
|
if (httpMethod.equals(HttpMethod.PATCH)) {
|
||||||
|
// as of the OData spec, in case of PATCH, the existing property is not touched
|
||||||
|
continue; // do nothing
|
||||||
|
} else if (httpMethod.equals(HttpMethod.PUT)) {
|
||||||
|
// as of the OData spec, in case of PUT, the existing property is set to null (or to default value)
|
||||||
|
existingProp.setValue(existingProp.getValueType(), null);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// change the value of the properties
|
||||||
|
existingProp.setValue(existingProp.getValueType(), updateProperty.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams)
|
||||||
|
throws ODataApplicationException {
|
||||||
|
|
||||||
|
Entity productEntity = getProduct(edmEntityType, keyParams);
|
||||||
|
if (productEntity == null) {
|
||||||
|
throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.productList.remove(productEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Entity createProduct(EdmEntityType edmEntityType, Entity entity) {
|
||||||
|
|
||||||
|
// the ID of the newly created product entity is generated automatically
|
||||||
|
int newId = 1;
|
||||||
|
while (productIdExists(newId)) {
|
||||||
|
newId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Property idProperty = entity.getProperty("ID");
|
||||||
|
if (idProperty != null) {
|
||||||
|
idProperty.setValue(ValueType.PRIMITIVE, new Integer(newId));
|
||||||
|
} else {
|
||||||
|
// as of OData v4 spec, the key property can be omitted from the POST request body
|
||||||
|
entity.getProperties().add(new Property(null, "ID", ValueType.PRIMITIVE, newId));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.productList.add(entity);
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean productIdExists(int id) {
|
||||||
|
|
||||||
|
for (Entity entity : this.productList) {
|
||||||
|
Integer existingID = (Integer) entity.getProperty("ID").getValue();
|
||||||
|
if (existingID.intValue() == id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* HELPER */
|
/* HELPER */
|
||||||
|
|
||||||
|
private boolean isKey(EdmEntityType edmEntityType, String propertyName) {
|
||||||
|
List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
|
||||||
|
for (EdmKeyPropertyRef propRef : keyPropertyRefs) {
|
||||||
|
String keyPropertyName = propRef.getName();
|
||||||
|
if (keyPropertyName.equals(propertyName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void initProductSampleData() {
|
private void initProductSampleData() {
|
||||||
|
|
||||||
Entity entity = new Entity();
|
Entity entity = new Entity();
|
||||||
|
|
|
@ -18,11 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package myservice.mynamespace.service;
|
package myservice.mynamespace.service;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import myservice.mynamespace.data.Storage;
|
|
||||||
|
|
||||||
import org.apache.olingo.commons.api.Constants;
|
import org.apache.olingo.commons.api.Constants;
|
||||||
import org.apache.olingo.commons.api.data.ContextURL;
|
import org.apache.olingo.commons.api.data.ContextURL;
|
||||||
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
|
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
|
||||||
|
@ -36,6 +35,7 @@ import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||||
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
|
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
|
||||||
import org.apache.olingo.commons.api.format.ContentType;
|
import org.apache.olingo.commons.api.format.ContentType;
|
||||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||||
|
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
import org.apache.olingo.server.api.OData;
|
import org.apache.olingo.server.api.OData;
|
||||||
import org.apache.olingo.server.api.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
|
@ -43,6 +43,8 @@ import org.apache.olingo.server.api.ODataRequest;
|
||||||
import org.apache.olingo.server.api.ODataResponse;
|
import org.apache.olingo.server.api.ODataResponse;
|
||||||
import org.apache.olingo.server.api.ServiceMetadata;
|
import org.apache.olingo.server.api.ServiceMetadata;
|
||||||
import org.apache.olingo.server.api.deserializer.DeserializerException;
|
import org.apache.olingo.server.api.deserializer.DeserializerException;
|
||||||
|
import org.apache.olingo.server.api.deserializer.DeserializerResult;
|
||||||
|
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
|
||||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||||
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||||
|
@ -57,10 +59,13 @@ import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||||
|
|
||||||
|
import myservice.mynamespace.data.Storage;
|
||||||
|
import myservice.mynamespace.util.Util;
|
||||||
|
|
||||||
public class DemoEntityProcessor implements EntityProcessor {
|
public class DemoEntityProcessor implements EntityProcessor {
|
||||||
|
|
||||||
private OData odata;
|
private OData odata;
|
||||||
private ServiceMetadata srvMetadata;
|
private ServiceMetadata serviceMetadata;
|
||||||
private Storage storage;
|
private Storage storage;
|
||||||
|
|
||||||
public DemoEntityProcessor(Storage storage) {
|
public DemoEntityProcessor(Storage storage) {
|
||||||
|
@ -69,21 +74,73 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
|
|
||||||
public void init(OData odata, ServiceMetadata serviceMetadata) {
|
public void init(OData odata, ServiceMetadata serviceMetadata) {
|
||||||
this.odata = odata;
|
this.odata = odata;
|
||||||
this.srvMetadata = serviceMetadata;
|
this.serviceMetadata = serviceMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
|
public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
|
||||||
throws ODataApplicationException, SerializerException {
|
throws ODataApplicationException, SerializerException {
|
||||||
|
|
||||||
// 1. retrieve the Entity Type
|
EdmEntityType responseEdmEntityType = null; // we'll need this to build the ContextURL
|
||||||
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
Entity responseEntity = null; // required for serialization of the response body
|
||||||
// Note: only in our example we can assume that the first segment is the EntitySet
|
EdmEntitySet responseEdmEntitySet = null; // we need this for building the contextUrl
|
||||||
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
|
|
||||||
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
|
||||||
|
|
||||||
// 2. retrieve the data from backend
|
// 1st step: retrieve the requested Entity: can be "normal" read operation, or navigation (to-one)
|
||||||
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
|
List<UriResource> resourceParts = uriInfo.getUriResourceParts();
|
||||||
Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
|
int segmentCount = resourceParts.size();
|
||||||
|
|
||||||
|
UriResource uriResource = resourceParts.get(0); // in our example, the first segment is the EntitySet
|
||||||
|
if (!(uriResource instanceof UriResourceEntitySet)) {
|
||||||
|
throw new ODataApplicationException("Only EntitySet is supported",
|
||||||
|
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
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); // in our example we don't support more complex URIs
|
||||||
|
if (navSegment instanceof UriResourceNavigation) {
|
||||||
|
UriResourceNavigation uriResourceNavigation = (UriResourceNavigation) navSegment;
|
||||||
|
EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
|
||||||
|
responseEdmEntityType = edmNavigationProperty.getType();
|
||||||
|
// contextURL displays the last segment
|
||||||
|
responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
|
||||||
|
|
||||||
|
// 2nd: fetch the data from backend.
|
||||||
|
// e.g. for the URI: 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)
|
||||||
|
// the key for nav is used in this case: 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. apply system query options
|
// 3. apply system query options
|
||||||
|
|
||||||
|
@ -102,13 +159,13 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
EdmNavigationProperty edmNavigationProperty = null;
|
EdmNavigationProperty edmNavigationProperty = null;
|
||||||
ExpandItem expandItem = expandOption.getExpandItems().get(0);
|
ExpandItem expandItem = expandOption.getExpandItems().get(0);
|
||||||
if(expandItem.isStar()) {
|
if(expandItem.isStar()) {
|
||||||
List<EdmNavigationPropertyBinding> bindings = edmEntitySet.getNavigationPropertyBindings();
|
List<EdmNavigationPropertyBinding> bindings = responseEdmEntitySet.getNavigationPropertyBindings();
|
||||||
// we know that there are navigation bindings
|
// we know that there are navigation bindings
|
||||||
// however normally in this case a check if navigation bindings exists is done
|
// however normally in this case a check if navigation bindings exists is done
|
||||||
if(!bindings.isEmpty()) {
|
if(!bindings.isEmpty()) {
|
||||||
// can in our case only be 'Category' or 'Products', so we can take the first
|
// can in our case only be 'Category' or 'Products', so we can take the first
|
||||||
EdmNavigationPropertyBinding binding = bindings.get(0);
|
EdmNavigationPropertyBinding binding = bindings.get(0);
|
||||||
EdmElement property = edmEntitySet.getEntityType().getProperty(binding.getPath());
|
EdmElement property = responseEdmEntitySet.getEntityType().getProperty(binding.getPath());
|
||||||
// we don't need to handle error cases, as it is done in the Olingo library
|
// we don't need to handle error cases, as it is done in the Olingo library
|
||||||
if(property instanceof EdmNavigationProperty) {
|
if(property instanceof EdmNavigationProperty) {
|
||||||
edmNavigationProperty = (EdmNavigationProperty) property;
|
edmNavigationProperty = (EdmNavigationProperty) property;
|
||||||
|
@ -116,10 +173,10 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// can be 'Category' or 'Products', no path supported
|
// can be 'Category' or 'Products', no path supported
|
||||||
UriResource uriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
|
UriResource expandUriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
|
||||||
// we don't need to handle error cases, as it is done in the Olingo library
|
// we don't need to handle error cases, as it is done in the Olingo library
|
||||||
if(uriResource instanceof UriResourceNavigation) {
|
if(expandUriResource instanceof UriResourceNavigation) {
|
||||||
edmNavigationProperty = ((UriResourceNavigation) uriResource).getProperty();
|
edmNavigationProperty = ((UriResourceNavigation) expandUriResource).getProperty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,26 +194,26 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
if(edmNavigationProperty.isCollection()){ // in case of Categories(1)/$expand=Products
|
if(edmNavigationProperty.isCollection()){ // in case of Categories(1)/$expand=Products
|
||||||
// fetch the data for the $expand (to-many navigation) from backend
|
// fetch the data for the $expand (to-many navigation) from backend
|
||||||
// here we get the data for the expand
|
// here we get the data for the expand
|
||||||
EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(entity, expandEdmEntityType);
|
EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(responseEntity, expandEdmEntityType);
|
||||||
link.setInlineEntitySet(expandEntityCollection);
|
link.setInlineEntitySet(expandEntityCollection);
|
||||||
} else { // in case of Products(1)?$expand=Category
|
} else { // in case of Products(1)?$expand=Category
|
||||||
// fetch the data for the $expand (to-one navigation) from backend
|
// fetch the data for the $expand (to-one navigation) from backend
|
||||||
// here we get the data for the expand
|
// here we get the data for the expand
|
||||||
Entity expandEntity = storage.getRelatedEntity(entity, expandEdmEntityType);
|
Entity expandEntity = storage.getRelatedEntity(responseEntity, expandEdmEntityType);
|
||||||
link.setInlineEntity(expandEntity);
|
link.setInlineEntity(expandEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the link - containing the expanded data - to the current entity
|
// set the link - containing the expanded data - to the current entity
|
||||||
entity.getNavigationLinks().add(link);
|
responseEntity.getNavigationLinks().add(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 4. serialize
|
// 4. serialize
|
||||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
EdmEntityType edmEntityType = responseEdmEntitySet.getEntityType();
|
||||||
// we need the property names of the $select, in order to build the context URL
|
// we need the property names of the $select, in order to build the context URL
|
||||||
String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType, expandOption, selectOption);
|
String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType, expandOption, selectOption);
|
||||||
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet)
|
ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet)
|
||||||
.selectList(selectList)
|
.selectList(selectList)
|
||||||
.suffix(Suffix.ENTITY).build();
|
.suffix(Suffix.ENTITY).build();
|
||||||
|
|
||||||
|
@ -169,34 +226,99 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
|
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
|
||||||
SerializerResult serializerResult = serializer.entity(srvMetadata, edmEntityType, entity, opts);
|
SerializerResult serializerResult = serializer.entity(serviceMetadata, edmEntityType, responseEntity, opts);
|
||||||
|
|
||||||
// 5. configure the response object
|
// 5. configure the response object
|
||||||
response.setContent(serializerResult.getContent());
|
response.setContent(serializerResult.getContent());
|
||||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Example request:
|
||||||
/*
|
*
|
||||||
* These processor methods are not handled in this tutorial
|
* POST URL: http://localhost:8080/DemoService/DemoService.svc/Products
|
||||||
*/
|
* Header: Content-Type: application/json; odata.metadata=minimal
|
||||||
|
* Request body:
|
||||||
|
{
|
||||||
|
"ID":3,
|
||||||
|
"Name":"Ergo Screen",
|
||||||
|
"Description":"17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"
|
||||||
|
}
|
||||||
|
* */
|
||||||
public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||||
ContentType requestFormat, ContentType responseFormat)
|
ContentType requestFormat, ContentType responseFormat)
|
||||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||||
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
|
||||||
|
// 1. Retrieve the entity type from the URI
|
||||||
|
EdmEntitySet edmEntitySet = Util.getEdmEntitySet(uriInfo);
|
||||||
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
|
// 2. create the data in backend
|
||||||
|
// 2.1. retrieve the payload from the POST request for the entity to create and deserialize it
|
||||||
|
InputStream requestInputStream = request.getBody();
|
||||||
|
ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
|
||||||
|
DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType);
|
||||||
|
Entity requestEntity = result.getEntity();
|
||||||
|
// 2.2 do the creation in backend, which returns the newly created entity
|
||||||
|
Entity createdEntity = storage.createEntityData(edmEntitySet, requestEntity);
|
||||||
|
|
||||||
|
// 3. serialize the response (we have to return the created entity)
|
||||||
|
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
|
||||||
|
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build(); // expand and select currently not supported
|
||||||
|
|
||||||
|
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
|
||||||
|
SerializerResult serializedResponse = serializer.entity(serviceMetadata, edmEntityType, createdEntity, options);
|
||||||
|
|
||||||
|
//4. configure the response object
|
||||||
|
response.setContent(serializedResponse.getContent());
|
||||||
|
response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||||
ContentType requestFormat, ContentType responseFormat)
|
ContentType requestFormat, ContentType responseFormat)
|
||||||
throws ODataApplicationException, DeserializerException, SerializerException {
|
throws ODataApplicationException, DeserializerException, SerializerException {
|
||||||
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
|
||||||
|
// 1. Retrieve the entity set which belongs to the requested entity
|
||||||
|
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();
|
||||||
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
|
// 2. update the data in backend
|
||||||
|
// 2.1. retrieve the payload from the PUT request for the entity to be updated
|
||||||
|
InputStream requestInputStream = request.getBody();
|
||||||
|
ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
|
||||||
|
DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType);
|
||||||
|
Entity requestEntity = result.getEntity();
|
||||||
|
// 2.2 do the modification in backend
|
||||||
|
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
|
||||||
|
// Note that this updateEntity()-method is invoked for both PUT or PATCH operations
|
||||||
|
HttpMethod httpMethod = request.getMethod();
|
||||||
|
storage.updateEntityData(edmEntitySet, keyPredicates, requestEntity, httpMethod);
|
||||||
|
|
||||||
|
//3. configure the response object
|
||||||
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
|
public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
|
||||||
throws ODataApplicationException {
|
throws ODataApplicationException {
|
||||||
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
|
||||||
|
// 1. Retrieve the entity set which belongs to the requested entity
|
||||||
|
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. delete the data in backend
|
||||||
|
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
|
||||||
|
storage.deleteEntityData(edmEntitySet, keyPredicates);
|
||||||
|
|
||||||
|
//3. configure the response object
|
||||||
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,29 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||||
import org.apache.olingo.commons.api.edm.EdmType;
|
import org.apache.olingo.commons.api.edm.EdmType;
|
||||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
import org.apache.olingo.server.api.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||||
import org.apache.olingo.server.api.uri.UriParameter;
|
import org.apache.olingo.server.api.uri.UriParameter;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResource;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||||
|
|
||||||
public class Util {
|
public class Util {
|
||||||
|
|
||||||
|
public static EdmEntitySet getEdmEntitySet(UriInfoResource uriInfo) throws ODataApplicationException {
|
||||||
|
|
||||||
|
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||||
|
// To get the entity set we have to interpret all URI segments
|
||||||
|
if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
|
||||||
|
// Here we should interpret the whole URI but in this example we do not support navigation so we throw an
|
||||||
|
// exception
|
||||||
|
throw new ODataApplicationException("Invalid resource type for first segment.", HttpStatusCode.NOT_IMPLEMENTED
|
||||||
|
.getStatusCode(), Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
|
||||||
|
|
||||||
|
return uriResource.getEntitySet();
|
||||||
|
}
|
||||||
|
|
||||||
public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
|
public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
|
||||||
List<UriParameter> keyParams) {
|
List<UriParameter> keyParams) {
|
||||||
|
|
||||||
|
@ -123,14 +142,14 @@ public class Util {
|
||||||
* The "Target" attribute specifies the target EntitySet
|
* The "Target" attribute specifies the target EntitySet
|
||||||
* Therefore we need the startEntitySet "Categories" in order to retrieve the target EntitySet "Products"
|
* Therefore we need the startEntitySet "Categories" in order to retrieve the target EntitySet "Products"
|
||||||
*/
|
*/
|
||||||
public static EdmEntitySet getNavigationTargetEntitySet(EdmEntitySet startEntitySet,
|
public static EdmEntitySet getNavigationTargetEntitySet(EdmEntitySet startEdmEntitySet,
|
||||||
EdmNavigationProperty edmNavigationProperty)
|
EdmNavigationProperty edmNavigationProperty)
|
||||||
throws ODataApplicationException {
|
throws ODataApplicationException {
|
||||||
|
|
||||||
EdmEntitySet navigationTargetEntitySet = null;
|
EdmEntitySet navigationTargetEntitySet = null;
|
||||||
|
|
||||||
String navPropName = edmNavigationProperty.getName();
|
String navPropName = edmNavigationProperty.getName();
|
||||||
EdmBindingTarget edmBindingTarget = startEntitySet.getRelatedBindingTarget(navPropName);
|
EdmBindingTarget edmBindingTarget = startEdmEntitySet.getRelatedBindingTarget(navPropName);
|
||||||
if (edmBindingTarget == null) {
|
if (edmBindingTarget == null) {
|
||||||
throw new ODataApplicationException("Not supported.",
|
throw new ODataApplicationException("Not supported.",
|
||||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||||
|
|
|
@ -125,14 +125,14 @@ public class Util {
|
||||||
* The "Target" attribute specifies the target EntitySet
|
* The "Target" attribute specifies the target EntitySet
|
||||||
* Therefore we need the startEntitySet "Categories" in order to retrieve the target EntitySet "Products"
|
* Therefore we need the startEntitySet "Categories" in order to retrieve the target EntitySet "Products"
|
||||||
*/
|
*/
|
||||||
public static EdmEntitySet getNavigationTargetEntitySet(EdmEntitySet startEntitySet,
|
public static EdmEntitySet getNavigationTargetEntitySet(EdmEntitySet startEdmEntitySet,
|
||||||
EdmNavigationProperty edmNavigationProperty)
|
EdmNavigationProperty edmNavigationProperty)
|
||||||
throws ODataApplicationException {
|
throws ODataApplicationException {
|
||||||
|
|
||||||
EdmEntitySet navigationTargetEntitySet = null;
|
EdmEntitySet navigationTargetEntitySet = null;
|
||||||
|
|
||||||
String navPropName = edmNavigationProperty.getName();
|
String navPropName = edmNavigationProperty.getName();
|
||||||
EdmBindingTarget edmBindingTarget = startEntitySet.getRelatedBindingTarget(navPropName);
|
EdmBindingTarget edmBindingTarget = startEdmEntitySet.getRelatedBindingTarget(navPropName);
|
||||||
if (edmBindingTarget == null) {
|
if (edmBindingTarget == null) {
|
||||||
throw new ODataApplicationException("Not supported.",
|
throw new ODataApplicationException("Not supported.",
|
||||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||||
|
|
Loading…
Reference in New Issue