[OLINGO-713] Updated Tutorial p0 with action/function importrs
This commit is contained in:
parent
d483c8fd1e
commit
1051f9b6cf
|
@ -39,7 +39,9 @@ import org.apache.olingo.commons.api.ex.ODataRuntimeException;
|
||||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
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.ODataApplicationException;
|
import org.apache.olingo.server.api.ODataApplicationException;
|
||||||
|
import org.apache.olingo.server.api.ServiceMetadata;
|
||||||
import org.apache.olingo.server.api.uri.UriParameter;
|
import org.apache.olingo.server.api.uri.UriParameter;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||||
|
|
||||||
public class Storage {
|
public class Storage {
|
||||||
|
|
||||||
|
@ -59,30 +61,97 @@ public class Storage {
|
||||||
|
|
||||||
/* PUBLIC FACADE */
|
/* PUBLIC FACADE */
|
||||||
|
|
||||||
public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet) {
|
public Entity readFunctionImportEntity(final UriResourceFunction uriResourceFunction,
|
||||||
EntityCollection entitySet = null;
|
final ServiceMetadata serviceMetadata) throws ODataApplicationException {
|
||||||
|
|
||||||
if (edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)) {
|
final EntityCollection entityCollection = readFunctionImportCollection(uriResourceFunction, serviceMetadata);
|
||||||
entitySet = getProducts();
|
final EdmEntityType edmEntityType = (EdmEntityType) uriResourceFunction.getFunction().getReturnType().getType();
|
||||||
} else if (edmEntitySet.getName().equals(DemoEdmProvider.ES_CATEGORIES_NAME)) {
|
|
||||||
entitySet = getCategories();
|
|
||||||
}
|
|
||||||
|
|
||||||
return entitySet;
|
return Util.findEntity(edmEntityType, entityCollection, uriResourceFunction.getKeyPredicates());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams) {
|
public EntityCollection readFunctionImportCollection(final UriResourceFunction uriResourceFunction,
|
||||||
Entity entity = null;
|
final ServiceMetadata serviceMetadata) throws ODataApplicationException {
|
||||||
|
|
||||||
|
if (DemoEdmProvider.FUNCTION_COUNT_CATEGORIES.equals(uriResourceFunction.getFunctionImport().getName())) {
|
||||||
|
// Get the parameter of the function
|
||||||
|
final UriParameter parameterAmount = uriResourceFunction.getParameters().get(0);
|
||||||
|
// Try to convert the parameter to an Integer.
|
||||||
|
// We have to take care, that the type of parameter fits to its EDM declaration
|
||||||
|
int amount;
|
||||||
|
try {
|
||||||
|
amount = Integer.parseInt(parameterAmount.getText());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ODataApplicationException("Type of parameter Amount must be Edm.Int32", HttpStatusCode.BAD_REQUEST
|
||||||
|
.getStatusCode(), Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
final EdmEntityType productEntityType = serviceMetadata.getEdm().getEntityType(DemoEdmProvider.ET_PRODUCT_FQN);
|
||||||
|
final List<Entity> resultEntityList = new ArrayList<Entity>();
|
||||||
|
|
||||||
|
// Loop over all categories and check how many products are linked
|
||||||
|
for (final Entity category : categoryList) {
|
||||||
|
final EntityCollection products = getRelatedEntityCollection(category, productEntityType);
|
||||||
|
if (products.getEntities().size() == amount) {
|
||||||
|
resultEntityList.add(category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final EntityCollection resultCollection = new EntityCollection();
|
||||||
|
resultCollection.getEntities().addAll(resultEntityList);
|
||||||
|
return resultCollection;
|
||||||
|
} else {
|
||||||
|
throw new ODataApplicationException("Function not implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),
|
||||||
|
Locale.ROOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetDataSet() {
|
||||||
|
resetDataSet(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetDataSet(final int amount) {
|
||||||
|
// Replace the old lists with empty ones
|
||||||
|
productList = new ArrayList<Entity>();
|
||||||
|
categoryList = new ArrayList<Entity>();
|
||||||
|
|
||||||
|
// Create new sample data
|
||||||
|
initProductSampleData();
|
||||||
|
initCategorySampleData();
|
||||||
|
|
||||||
|
// Truncate the lists
|
||||||
|
if (amount < productList.size()) {
|
||||||
|
productList = productList.subList(0, amount);
|
||||||
|
// Products 0, 1 are linked to category 0
|
||||||
|
// Products 2, 3 are linked to category 1
|
||||||
|
// Products 4, 5 are linked to category 2
|
||||||
|
categoryList = categoryList.subList(0, (amount / 2) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet) throws ODataApplicationException {
|
||||||
|
|
||||||
|
if (edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)) {
|
||||||
|
return getEntityCollection(productList);
|
||||||
|
} else if (edmEntitySet.getName().equals(DemoEdmProvider.ES_CATEGORIES_NAME)) {
|
||||||
|
return getEntityCollection(categoryList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams)
|
||||||
|
throws ODataApplicationException {
|
||||||
|
|
||||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
|
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
|
||||||
entity = getProduct(edmEntityType, keyParams);
|
return getEntity(edmEntityType, keyParams, productList);
|
||||||
} else if (edmEntityType.getName().equals(DemoEdmProvider.ET_CATEGORY_NAME)) {
|
} else if (edmEntityType.getName().equals(DemoEdmProvider.ET_CATEGORY_NAME)) {
|
||||||
entity = getCategory(edmEntityType, keyParams);
|
return getEntity(edmEntityType, keyParams, categoryList);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entity;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
|
@ -109,37 +178,31 @@ public class Storage {
|
||||||
|
|
||||||
if (sourceEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString())
|
if (sourceEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString())
|
||||||
&& relatedEntityFqn.equals(DemoEdmProvider.ET_CATEGORY_FQN)) {
|
&& relatedEntityFqn.equals(DemoEdmProvider.ET_CATEGORY_FQN)) {
|
||||||
navigationTargetEntityCollection.setId(createId(sourceEntity, "ID", DemoEdmProvider.NAV_TO_CATEGORY));
|
|
||||||
// relation Products->Category (result all categories)
|
// relation Products->Category (result all categories)
|
||||||
int productID = (Integer) sourceEntity.getProperty("ID").getValue();
|
int productID = (Integer) sourceEntity.getProperty("ID").getValue();
|
||||||
if (productID == 1 || productID == 2) {
|
if (productID == 0 || productID == 1) {
|
||||||
navigationTargetEntityCollection.getEntities().add(categoryList.get(0));
|
navigationTargetEntityCollection.getEntities().add(categoryList.get(0));
|
||||||
} else if (productID == 3 || productID == 4) {
|
} else if (productID == 2 || productID == 3) {
|
||||||
navigationTargetEntityCollection.getEntities().add(categoryList.get(1));
|
navigationTargetEntityCollection.getEntities().add(categoryList.get(1));
|
||||||
} else if (productID == 5 || productID == 6) {
|
} else if (productID == 4 || productID == 5) {
|
||||||
navigationTargetEntityCollection.getEntities().add(categoryList.get(2));
|
navigationTargetEntityCollection.getEntities().add(categoryList.get(2));
|
||||||
}
|
}
|
||||||
} else if (sourceEntityFqn.equals(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString())
|
} else if (sourceEntityFqn.equals(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString())
|
||||||
&& relatedEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN)) {
|
&& relatedEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN)) {
|
||||||
navigationTargetEntityCollection.setId(createId(sourceEntity, "ID", DemoEdmProvider.NAV_TO_PRODUCTS));
|
|
||||||
// relation Category->Products (result all products)
|
// relation Category->Products (result all products)
|
||||||
int categoryID = (Integer) sourceEntity.getProperty("ID").getValue();
|
int categoryID = (Integer) sourceEntity.getProperty("ID").getValue();
|
||||||
if (categoryID == 1) {
|
if (categoryID == 0) {
|
||||||
// the first 2 products are notebooks
|
// the first 2 products are notebooks
|
||||||
navigationTargetEntityCollection.getEntities().addAll(productList.subList(0, 2));
|
navigationTargetEntityCollection.getEntities().addAll(productList.subList(0, 2));
|
||||||
} else if (categoryID == 2) {
|
} else if (categoryID == 1) {
|
||||||
// the next 2 products are organizers
|
// the next 2 products are organizers
|
||||||
navigationTargetEntityCollection.getEntities().addAll(productList.subList(2, 4));
|
navigationTargetEntityCollection.getEntities().addAll(productList.subList(2, 4));
|
||||||
} else if (categoryID == 3) {
|
} else if (categoryID == 2) {
|
||||||
// the first 2 products are monitors
|
// the first 2 products are monitors
|
||||||
navigationTargetEntityCollection.getEntities().addAll(productList.subList(4, 6));
|
navigationTargetEntityCollection.getEntities().addAll(productList.subList(4, 6));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navigationTargetEntityCollection.getEntities().isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return navigationTargetEntityCollection;
|
return navigationTargetEntityCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,9 +210,10 @@ public class Storage {
|
||||||
|
|
||||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
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)) {
|
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
|
||||||
return createProduct(edmEntityType, entityToCreate);
|
return createEntity(edmEntityType, entityToCreate, productList);
|
||||||
|
} else if (edmEntityType.getName().equals(DemoEdmProvider.ET_CATEGORY_NAME)) {
|
||||||
|
return createEntity(edmEntityType, entityToCreate, categoryList);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -157,15 +221,16 @@ public class Storage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is invoked for PATCH or PUT requests
|
* This method is invoked for PATCH or PUT requests
|
||||||
* */
|
*/
|
||||||
public void updateEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams, Entity updateEntity,
|
public void updateEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams, Entity updateEntity,
|
||||||
HttpMethod httpMethod) throws ODataApplicationException {
|
HttpMethod httpMethod) throws ODataApplicationException {
|
||||||
|
|
||||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
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)) {
|
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
|
||||||
updateProduct(edmEntityType, keyParams, updateEntity, httpMethod);
|
updateEntity(edmEntityType, keyParams, updateEntity, httpMethod, productList);
|
||||||
|
} else if (edmEntityType.getName().equals(DemoEdmProvider.ET_CATEGORY_NAME)) {
|
||||||
|
updateEntity(edmEntityType, keyParams, updateEntity, httpMethod, categoryList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,63 +239,86 @@ public class Storage {
|
||||||
|
|
||||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
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)) {
|
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
|
||||||
deleteProduct(edmEntityType, keyParams);
|
deleteEntity(edmEntityType, keyParams, productList);
|
||||||
|
} else if (edmEntityType.getName().equals(DemoEdmProvider.ET_CATEGORY_NAME)) {
|
||||||
|
deleteEntity(edmEntityType, keyParams, categoryList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* INTERNAL */
|
/* INTERNAL */
|
||||||
|
|
||||||
private EntityCollection getProducts() {
|
private Entity createEntity(EdmEntityType edmEntityType, Entity entity, List<Entity> entityList) {
|
||||||
EntityCollection retEntitySet = new EntityCollection();
|
|
||||||
|
|
||||||
for (Entity productEntity : this.productList) {
|
// the ID of the newly created entity is generated automatically
|
||||||
retEntitySet.getEntities().add(productEntity);
|
int newId = 1;
|
||||||
|
while (entityIdExists(newId, entityList)) {
|
||||||
|
newId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Property idProperty = entity.getProperty("ID");
|
||||||
|
if (idProperty != null) {
|
||||||
|
idProperty.setValue(ValueType.PRIMITIVE, Integer.valueOf(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));
|
||||||
|
}
|
||||||
|
entity.setId(createId(entity, "ID"));
|
||||||
|
entityList.add(entity);
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityCollection getEntityCollection(final List<Entity> entityList) {
|
||||||
|
|
||||||
|
EntityCollection retEntitySet = new EntityCollection();
|
||||||
|
retEntitySet.getEntities().addAll(entityList);
|
||||||
|
|
||||||
return retEntitySet;
|
return retEntitySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams) {
|
private Entity getEntity(EdmEntityType edmEntityType, List<UriParameter> keyParams, List<Entity> entityList)
|
||||||
|
throws ODataApplicationException {
|
||||||
|
|
||||||
// the list of entities at runtime
|
// the list of entities at runtime
|
||||||
EntityCollection entityCollection = getProducts();
|
EntityCollection entitySet = getEntityCollection(entityList);
|
||||||
|
|
||||||
/* generic approach to find the requested entity */
|
/* generic approach to find the requested entity */
|
||||||
return Util.findEntity(edmEntityType, entityCollection, keyParams);
|
Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams);
|
||||||
}
|
|
||||||
|
|
||||||
private EntityCollection getCategories() {
|
if (requestedEntity == null) {
|
||||||
EntityCollection entitySet = new EntityCollection();
|
// this variable is null if our data doesn't contain an entity for the requested key
|
||||||
|
// Throw suitable exception
|
||||||
for (Entity categoryEntity : this.categoryList) {
|
throw new ODataApplicationException("Entity for requested key doesn't exist",
|
||||||
entitySet.getEntities().add(categoryEntity);
|
HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entitySet;
|
return requestedEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entity getCategory(EdmEntityType edmEntityType, List<UriParameter> keyParams) {
|
private boolean entityIdExists(int id, List<Entity> entityList) {
|
||||||
|
|
||||||
// the list of entities at runtime
|
for (Entity entity : entityList) {
|
||||||
EntityCollection entitySet = getCategories();
|
Integer existingID = (Integer) entity.getProperty("ID").getValue();
|
||||||
|
if (existingID.intValue() == id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* generic approach to find the requested entity */
|
return false;
|
||||||
return Util.findEntity(edmEntityType, entitySet, keyParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams, Entity entity,
|
private void updateEntity(EdmEntityType edmEntityType, List<UriParameter> keyParams, Entity updateEntity,
|
||||||
HttpMethod httpMethod) throws ODataApplicationException {
|
HttpMethod httpMethod, List<Entity> entityList) throws ODataApplicationException {
|
||||||
|
|
||||||
Entity productEntity = getProduct(edmEntityType, keyParams);
|
Entity entity = getEntity(edmEntityType, keyParams, entityList);
|
||||||
if (productEntity == null) {
|
if (entity == null) {
|
||||||
throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
|
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
|
// 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
|
// Note: ignoring ComplexType, as we don't have it in our odata model
|
||||||
List<Property> existingProperties = productEntity.getProperties();
|
List<Property> existingProperties = entity.getProperties();
|
||||||
for (Property existingProp : existingProperties) {
|
for (Property existingProp : existingProperties) {
|
||||||
String propName = existingProp.getName();
|
String propName = existingProp.getName();
|
||||||
|
|
||||||
|
@ -239,7 +327,7 @@ public class Storage {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Property updateProperty = entity.getProperty(propName);
|
Property updateProperty = updateEntity.getProperty(propName);
|
||||||
// the request payload might not consider ALL properties, so it can be null
|
// the request payload might not consider ALL properties, so it can be null
|
||||||
if (updateProperty == null) {
|
if (updateProperty == null) {
|
||||||
// if a property has NOT been added to the request payload
|
// if a property has NOT been added to the request payload
|
||||||
|
@ -258,54 +346,18 @@ public class Storage {
|
||||||
existingProp.setValue(existingProp.getValueType(), updateProperty.getValue());
|
existingProp.setValue(existingProp.getValueType(), updateProperty.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams)
|
private void deleteEntity(EdmEntityType edmEntityType, List<UriParameter> keyParams, List<Entity> entityList)
|
||||||
throws ODataApplicationException {
|
throws ODataApplicationException {
|
||||||
|
|
||||||
Entity productEntity = getProduct(edmEntityType, keyParams);
|
Entity entity = getEntity(edmEntityType, keyParams, entityList);
|
||||||
if (productEntity == null) {
|
if (entity == null) {
|
||||||
throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
|
throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.productList.remove(productEntity);
|
entityList.remove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
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, Integer.valueOf(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));
|
|
||||||
}
|
|
||||||
entity.setId(createId(entity, "ID"));
|
|
||||||
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 */
|
|
||||||
|
|
||||||
private boolean isKey(EdmEntityType edmEntityType, String propertyName) {
|
private boolean isKey(EdmEntityType edmEntityType, String propertyName) {
|
||||||
List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
|
List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
|
||||||
for (EdmKeyPropertyRef propRef : keyPropertyRefs) {
|
for (EdmKeyPropertyRef propRef : keyPropertyRefs) {
|
||||||
|
@ -316,12 +368,12 @@ public class Storage {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initProductSampleData() {
|
private void initProductSampleData() {
|
||||||
|
|
||||||
Entity entity = new Entity();
|
Entity entity = new Entity();
|
||||||
|
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 0));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"));
|
"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"));
|
||||||
|
@ -330,7 +382,7 @@ public class Storage {
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
|
||||||
entity = new Entity();
|
entity = new Entity();
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Professional 17"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Professional 17"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"Notebook Professional, 2.8GHz - 15 XGA - 8GB DDR3 RAM - 500GB"));
|
"Notebook Professional, 2.8GHz - 15 XGA - 8GB DDR3 RAM - 500GB"));
|
||||||
|
@ -339,7 +391,7 @@ public class Storage {
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
|
||||||
entity = new Entity();
|
entity = new Entity();
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"));
|
"Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"));
|
||||||
|
@ -348,7 +400,7 @@ public class Storage {
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
|
||||||
entity = new Entity();
|
entity = new Entity();
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 4));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Comfort Easy"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Comfort Easy"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"32 GB Digital Assitant with high-resolution color screen"));
|
"32 GB Digital Assitant with high-resolution color screen"));
|
||||||
|
@ -357,7 +409,7 @@ public class Storage {
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
|
||||||
entity = new Entity();
|
entity = new Entity();
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 5));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 4));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"));
|
"19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"));
|
||||||
|
@ -366,7 +418,7 @@ public class Storage {
|
||||||
productList.add(entity);
|
productList.add(entity);
|
||||||
|
|
||||||
entity = new Entity();
|
entity = new Entity();
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 6));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 5));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Flat Basic"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Flat Basic"));
|
||||||
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
|
||||||
"Optimum Hi-Resolution max. 1600 x 1200 @ 85Hz, Dot Pitch: 0.24mm"));
|
"Optimum Hi-Resolution max. 1600 x 1200 @ 85Hz, Dot Pitch: 0.24mm"));
|
||||||
|
@ -379,21 +431,21 @@ public class Storage {
|
||||||
|
|
||||||
Entity entity = new Entity();
|
Entity entity = new Entity();
|
||||||
|
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 0));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebooks"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebooks"));
|
||||||
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
categoryList.add(entity);
|
categoryList.add(entity);
|
||||||
|
|
||||||
entity = new Entity();
|
entity = new Entity();
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Organizers"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Organizers"));
|
||||||
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
categoryList.add(entity);
|
categoryList.add(entity);
|
||||||
|
|
||||||
entity = new Entity();
|
entity = new Entity();
|
||||||
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3));
|
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2));
|
||||||
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Monitors"));
|
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Monitors"));
|
||||||
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
|
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
|
||||||
entity.setId(createId(entity, "ID"));
|
entity.setId(createId(entity, "ID"));
|
||||||
|
@ -409,7 +461,7 @@ public class Storage {
|
||||||
StringBuilder sb = new StringBuilder(getEntitySetName(entity)).append("(");
|
StringBuilder sb = new StringBuilder(getEntitySetName(entity)).append("(");
|
||||||
final Property property = entity.getProperty(idPropertyName);
|
final Property property = entity.getProperty(idPropertyName);
|
||||||
sb.append(property.asPrimitive()).append(")");
|
sb.append(property.asPrimitive()).append(")");
|
||||||
if(navigationName != null) {
|
if (navigationName != null) {
|
||||||
sb.append("/").append(navigationName);
|
sb.append("/").append(navigationName);
|
||||||
}
|
}
|
||||||
return new URI(sb.toString());
|
return new URI(sb.toString());
|
||||||
|
@ -419,9 +471,9 @@ public class Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEntitySetName(Entity entity) {
|
private String getEntitySetName(Entity entity) {
|
||||||
if(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString().equals(entity.getType())) {
|
if (DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString().equals(entity.getType())) {
|
||||||
return DemoEdmProvider.ES_CATEGORIES_NAME;
|
return DemoEdmProvider.ES_CATEGORIES_NAME;
|
||||||
} else if(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString().equals(entity.getType())) {
|
} else if (DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString().equals(entity.getType())) {
|
||||||
return DemoEdmProvider.ES_PRODUCTS_NAME;
|
return DemoEdmProvider.ES_PRODUCTS_NAME;
|
||||||
}
|
}
|
||||||
return entity.getType();
|
return entity.getType();
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package myservice.mynamespace.service;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.data.Parameter;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmAction;
|
||||||
|
import org.apache.olingo.commons.api.format.ContentType;
|
||||||
|
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.deserializer.ODataDeserializer;
|
||||||
|
import org.apache.olingo.server.api.processor.ActionVoidProcessor;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceAction;
|
||||||
|
|
||||||
|
import myservice.mynamespace.data.Storage;
|
||||||
|
|
||||||
|
public class DemoActionProcessor implements ActionVoidProcessor {
|
||||||
|
|
||||||
|
private OData odata;
|
||||||
|
private Storage storage;
|
||||||
|
|
||||||
|
public DemoActionProcessor(final Storage storage) {
|
||||||
|
this.storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(final OData odata, final ServiceMetadata serviceMetadata) {
|
||||||
|
this.odata = odata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processActionVoid(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||||
|
ContentType requestFormat) throws ODataApplicationException, ODataLibraryException {
|
||||||
|
|
||||||
|
// 1st Get the action from the resource path
|
||||||
|
final EdmAction edmAction = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts()
|
||||||
|
.get(0)).getAction();
|
||||||
|
|
||||||
|
// 2nd Deserialize the parameter
|
||||||
|
// In our case there is only one action. So we can be sure that parameter "Amount" has been provided by the client
|
||||||
|
if (requestFormat == null) {
|
||||||
|
throw new ODataApplicationException("The content type has not been set in the request.",
|
||||||
|
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ODataDeserializer deserializer = odata.createDeserializer(requestFormat);
|
||||||
|
final Map<String, Parameter> actionParameter = deserializer.actionParameters(request.getBody(), edmAction)
|
||||||
|
.getActionParameters();
|
||||||
|
final Parameter parameterAmount = actionParameter.get(DemoEdmProvider.PARAMETER_AMOUNT);
|
||||||
|
|
||||||
|
// The parameter amount is nullable
|
||||||
|
if(parameterAmount.isNull()) {
|
||||||
|
storage.resetDataSet();
|
||||||
|
} else {
|
||||||
|
final Integer amount = (Integer) parameterAmount.asPrimitive();
|
||||||
|
storage.resetDataSet(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,14 +25,20 @@ import java.util.List;
|
||||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
|
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
|
||||||
|
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
|
||||||
|
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
|
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
|
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
|
import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
|
import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
|
||||||
|
import org.apache.olingo.commons.api.edm.provider.CsdlFunction;
|
||||||
|
import org.apache.olingo.commons.api.edm.provider.CsdlFunctionImport;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
|
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationPropertyBinding;
|
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationPropertyBinding;
|
||||||
|
import org.apache.olingo.commons.api.edm.provider.CsdlParameter;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
|
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
|
import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
|
||||||
|
import org.apache.olingo.commons.api.edm.provider.CsdlReturnType;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
|
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
|
||||||
|
|
||||||
public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
|
@ -57,6 +63,101 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
public static final String NAV_TO_CATEGORY = "Category";
|
public static final String NAV_TO_CATEGORY = "Category";
|
||||||
public static final String NAV_TO_PRODUCTS = "Products";
|
public static final String NAV_TO_PRODUCTS = "Products";
|
||||||
|
|
||||||
|
//Action
|
||||||
|
public static final String ACTION_RESET = "Reset";
|
||||||
|
public static final FullQualifiedName ACTION_RESET_FQN = new FullQualifiedName(NAMESPACE, ACTION_RESET);
|
||||||
|
|
||||||
|
// Function
|
||||||
|
public static final String FUNCTION_COUNT_CATEGORIES = "CountCategories";
|
||||||
|
public static final FullQualifiedName FUNCTION_COUNT_CATEGORIES_FQN
|
||||||
|
= new FullQualifiedName(NAMESPACE, FUNCTION_COUNT_CATEGORIES);
|
||||||
|
|
||||||
|
// Function/Action Parameters
|
||||||
|
public static final String PARAMETER_AMOUNT = "Amount";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CsdlAction> getActions(final FullQualifiedName actionName) {
|
||||||
|
if(actionName.equals(ACTION_RESET_FQN)) {
|
||||||
|
// It is allowed to overload actions, so we have to provide a list of Actions for each action name
|
||||||
|
final List<CsdlAction> actions = new ArrayList<CsdlAction>();
|
||||||
|
|
||||||
|
// Create parameters
|
||||||
|
final List<CsdlParameter> parameters = new ArrayList<CsdlParameter>();
|
||||||
|
final CsdlParameter parameter = new CsdlParameter();
|
||||||
|
parameter.setName(PARAMETER_AMOUNT);
|
||||||
|
parameter.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
|
||||||
|
parameters.add(parameter);
|
||||||
|
|
||||||
|
// Create the Csdl Action
|
||||||
|
final CsdlAction action = new CsdlAction();
|
||||||
|
action.setName(ACTION_RESET_FQN.getName());
|
||||||
|
action.setParameters(parameters);
|
||||||
|
actions.add(action);
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CsdlActionImport getActionImport(final FullQualifiedName entityContainer, final String actionImportName) {
|
||||||
|
if(entityContainer.equals(CONTAINER)) {
|
||||||
|
if(actionImportName.equals(ACTION_RESET_FQN.getName())) {
|
||||||
|
return new CsdlActionImport()
|
||||||
|
.setName(actionImportName)
|
||||||
|
.setAction(ACTION_RESET_FQN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CsdlFunction> getFunctions(final FullQualifiedName functionName) {
|
||||||
|
if (functionName.equals(FUNCTION_COUNT_CATEGORIES_FQN)) {
|
||||||
|
// It is allowed to overload functions, so we have to provide a list of functions for each function name
|
||||||
|
final List<CsdlFunction> functions = new ArrayList<CsdlFunction>();
|
||||||
|
|
||||||
|
// Create the parameter for the function
|
||||||
|
final CsdlParameter parameterAmount = new CsdlParameter();
|
||||||
|
parameterAmount.setName(PARAMETER_AMOUNT);
|
||||||
|
parameterAmount.setNullable(false);
|
||||||
|
parameterAmount.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
|
||||||
|
|
||||||
|
// Create the return type of the function
|
||||||
|
final CsdlReturnType returnType = new CsdlReturnType();
|
||||||
|
returnType.setCollection(true);
|
||||||
|
returnType.setType(ET_CATEGORY_FQN);
|
||||||
|
|
||||||
|
// Create the function
|
||||||
|
final CsdlFunction function = new CsdlFunction();
|
||||||
|
function.setName(FUNCTION_COUNT_CATEGORIES_FQN.getName())
|
||||||
|
.setParameters(Arrays.asList(parameterAmount))
|
||||||
|
.setReturnType(returnType);
|
||||||
|
functions.add(function);
|
||||||
|
|
||||||
|
return functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CsdlFunctionImport getFunctionImport(FullQualifiedName entityContainer, String functionImportName) {
|
||||||
|
if(entityContainer.equals(CONTAINER)) {
|
||||||
|
if(functionImportName.equals(FUNCTION_COUNT_CATEGORIES_FQN.getName())) {
|
||||||
|
return new CsdlFunctionImport()
|
||||||
|
.setName(functionImportName)
|
||||||
|
.setFunction(FUNCTION_COUNT_CATEGORIES_FQN)
|
||||||
|
.setEntitySet(ES_CATEGORIES_NAME)
|
||||||
|
.setIncludeInServiceDocument(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
|
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
|
||||||
|
|
||||||
|
@ -78,7 +179,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
|
|
||||||
// navigation property: many-to-one, null not allowed (product must have a category)
|
// navigation property: many-to-one, null not allowed (product must have a category)
|
||||||
CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName(NAV_TO_CATEGORY)
|
CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName(NAV_TO_CATEGORY)
|
||||||
.setType(ET_CATEGORY_FQN).setNullable(false).setPartner("Products");
|
.setType(ET_CATEGORY_FQN).setNullable(true).setPartner("Products");
|
||||||
List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
|
List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
|
||||||
navPropList.add(navProp);
|
navPropList.add(navProp);
|
||||||
|
|
||||||
|
@ -183,7 +284,17 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
entityTypes.add(getEntityType(ET_PRODUCT_FQN));
|
entityTypes.add(getEntityType(ET_PRODUCT_FQN));
|
||||||
entityTypes.add(getEntityType(ET_CATEGORY_FQN));
|
entityTypes.add(getEntityType(ET_CATEGORY_FQN));
|
||||||
schema.setEntityTypes(entityTypes);
|
schema.setEntityTypes(entityTypes);
|
||||||
|
|
||||||
|
// add actions
|
||||||
|
List<CsdlAction> actions = new ArrayList<CsdlAction>();
|
||||||
|
actions.addAll(getActions(ACTION_RESET_FQN));
|
||||||
|
schema.setActions(actions);
|
||||||
|
|
||||||
|
// add functions
|
||||||
|
List<CsdlFunction> functions = new ArrayList<CsdlFunction>();
|
||||||
|
functions.addAll(getFunctions(FUNCTION_COUNT_CATEGORIES_FQN));
|
||||||
|
schema.setFunctions(functions);
|
||||||
|
|
||||||
// add EntityContainer
|
// add EntityContainer
|
||||||
schema.setEntityContainer(getEntityContainer());
|
schema.setEntityContainer(getEntityContainer());
|
||||||
|
|
||||||
|
@ -201,10 +312,20 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
|
||||||
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
|
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
|
||||||
entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
|
entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
|
||||||
entitySets.add(getEntitySet(CONTAINER, ES_CATEGORIES_NAME));
|
entitySets.add(getEntitySet(CONTAINER, ES_CATEGORIES_NAME));
|
||||||
|
|
||||||
|
// Create function imports
|
||||||
|
List<CsdlFunctionImport> functionImports = new ArrayList<CsdlFunctionImport>();
|
||||||
|
functionImports.add(getFunctionImport(CONTAINER, FUNCTION_COUNT_CATEGORIES));
|
||||||
|
|
||||||
|
// Create action imports
|
||||||
|
List<CsdlActionImport> actionImports = new ArrayList<CsdlActionImport>();
|
||||||
|
actionImports.add(getActionImport(CONTAINER, ACTION_RESET));
|
||||||
|
|
||||||
// create EntityContainer
|
// create EntityContainer
|
||||||
CsdlEntityContainer entityContainer = new CsdlEntityContainer();
|
CsdlEntityContainer entityContainer = new CsdlEntityContainer();
|
||||||
entityContainer.setName(CONTAINER_NAME);
|
entityContainer.setName(CONTAINER_NAME);
|
||||||
|
entityContainer.setActionImports(actionImports);
|
||||||
|
entityContainer.setFunctionImports(functionImports);
|
||||||
entityContainer.setEntitySets(entitySets);
|
entityContainer.setEntitySets(entitySets);
|
||||||
|
|
||||||
return entityContainer;
|
return entityContainer;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package myservice.mynamespace.service;
|
package myservice.mynamespace.service;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -56,6 +57,7 @@ import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
import org.apache.olingo.server.api.uri.UriInfoResource;
|
import org.apache.olingo.server.api.uri.UriInfoResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResource;
|
import org.apache.olingo.server.api.uri.UriResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||||
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
|
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.CountOption;
|
import org.apache.olingo.server.api.uri.queryoption.CountOption;
|
||||||
|
@ -86,10 +88,54 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
|
||||||
this.serviceMetadata = serviceMetadata;
|
this.serviceMetadata = serviceMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
public void readEntityCollection(ODataRequest request, ODataResponse response,
|
||||||
ContentType responseFormat) throws ODataApplicationException, SerializerException {
|
UriInfo uriInfo, ContentType responseFormat)
|
||||||
|
throws ODataApplicationException, SerializerException {
|
||||||
|
|
||||||
|
final UriResource firstResourceSegment = uriInfo.getUriResourceParts().get(0);
|
||||||
|
|
||||||
|
if(firstResourceSegment instanceof UriResourceEntitySet) {
|
||||||
|
readEntityCollectionInternal(request, response, uriInfo, responseFormat);
|
||||||
|
} else if(firstResourceSegment instanceof UriResourceFunction) {
|
||||||
|
readFunctionImportCollection(request, response, uriInfo, responseFormat);
|
||||||
|
} else {
|
||||||
|
throw new ODataApplicationException("Not implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),
|
||||||
|
Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFunctionImportCollection(final ODataRequest request, final ODataResponse response,
|
||||||
|
final UriInfo uriInfo, final ContentType responseFormat) throws ODataApplicationException, SerializerException {
|
||||||
|
|
||||||
|
// 1st step: Analyze the URI and fetch the entity collection returned by the function import
|
||||||
|
// Function Imports are always the first segment of the resource path
|
||||||
|
final UriResource firstSegment = uriInfo.getUriResourceParts().get(0);
|
||||||
|
|
||||||
|
if(!(firstSegment instanceof UriResourceFunction)) {
|
||||||
|
throw new ODataApplicationException("Not implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),
|
||||||
|
Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
final UriResourceFunction uriResourceFunction = (UriResourceFunction) firstSegment;
|
||||||
|
final EntityCollection entityCol = storage.readFunctionImportCollection(uriResourceFunction, serviceMetadata);
|
||||||
|
|
||||||
|
// 2nd step: Serialize the response entity
|
||||||
|
final EdmEntityType edmEntityType = (EdmEntityType) uriResourceFunction.getFunction().getReturnType().getType();
|
||||||
|
final ContextURL contextURL = ContextURL.with().asCollection().type(edmEntityType).build();
|
||||||
|
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextURL).build();
|
||||||
|
final ODataSerializer serializer = odata.createSerializer(responseFormat);
|
||||||
|
final SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entityCol,
|
||||||
|
opts);
|
||||||
|
|
||||||
// 1st: retrieve the requested EntitySet from the uriInfo (representation of the parsed URI)
|
// 3rd configure the response object
|
||||||
|
response.setContent(serializerResult.getContent());
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readEntityCollectionInternal(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||||
|
ContentType responseFormat) throws ODataApplicationException, SerializerException {
|
||||||
|
// 1st: retrieve the requested EntitySet from the uriInfo (representation of the parsed URI)
|
||||||
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||||
// in our example, the first segment is the EntitySet
|
// in our example, the first segment is the EntitySet
|
||||||
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
|
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
|
||||||
|
@ -100,10 +146,10 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
|
||||||
EntityCollection modifiedEntityCollection = new EntityCollection();
|
EntityCollection modifiedEntityCollection = new EntityCollection();
|
||||||
List<Entity> modifiedEntityList = new ArrayList<Entity>();
|
List<Entity> modifiedEntityList = new ArrayList<Entity>();
|
||||||
modifiedEntityList.addAll(entityCollection.getEntities());
|
modifiedEntityList.addAll(entityCollection.getEntities());
|
||||||
|
|
||||||
// 3rd: Apply system query option
|
// 3rd: Apply system query option
|
||||||
// The system query options have to be applied in a defined order
|
// The system query options have to be applied in a defined order
|
||||||
// 3.1.) $filter
|
// 3.1.) $filter
|
||||||
modifiedEntityList = applyFilterQueryOption(modifiedEntityList, uriInfo.getFilterOption());
|
modifiedEntityList = applyFilterQueryOption(modifiedEntityList, uriInfo.getFilterOption());
|
||||||
// 3.2.) $orderby
|
// 3.2.) $orderby
|
||||||
modifiedEntityList = applyOrderQueryOption(modifiedEntityList, uriInfo.getOrderByOption());
|
modifiedEntityList = applyOrderQueryOption(modifiedEntityList, uriInfo.getOrderByOption());
|
||||||
|
@ -124,9 +170,9 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
|
||||||
|
|
||||||
// 4th: create a serializer based on the requested format (json)
|
// 4th: create a serializer based on the requested format (json)
|
||||||
ODataSerializer serializer = odata.createSerializer(responseFormat);
|
ODataSerializer serializer = odata.createSerializer(responseFormat);
|
||||||
|
|
||||||
// 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
|
||||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
String selectList = odata.createUriHelper()
|
String selectList = odata.createUriHelper()
|
||||||
.buildContextURLSelectList(edmEntityType, uriInfo.getExpandOption(), selectOption);
|
.buildContextURLSelectList(edmEntityType, uriInfo.getExpandOption(), selectOption);
|
||||||
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).selectList(selectList).build();
|
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).selectList(selectList).build();
|
||||||
|
@ -150,8 +196,8 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
|
||||||
response.setContent(serializedContent);
|
response.setContent(serializedContent);
|
||||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Entity> applyExpandQueryOption(List<Entity> modifiedEntityList,
|
private List<Entity> applyExpandQueryOption(List<Entity> modifiedEntityList,
|
||||||
EdmEntitySet edmEntitySet, ExpandOption expandOption) {
|
EdmEntitySet edmEntitySet, ExpandOption expandOption) {
|
||||||
|
|
||||||
|
@ -200,13 +246,14 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
|
||||||
// fetch the data for the $expand (to-many navigation) from backend
|
// fetch the data for the $expand (to-many navigation) from backend
|
||||||
EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(entity, expandEdmEntityType);
|
EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(entity, expandEdmEntityType);
|
||||||
link.setInlineEntitySet(expandEntityCollection);
|
link.setInlineEntitySet(expandEntityCollection);
|
||||||
link.setHref(expandEntityCollection.getId().toASCIIString());
|
final URI entityId = expandEntityCollection.getId();
|
||||||
|
link.setHref(entityId != null ? entityId.toASCIIString() : null);
|
||||||
} else { // in case of Products?$expand=Category
|
} else { // in case of Products?$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(entity, expandEdmEntityType);
|
||||||
link.setInlineEntity(expandEntity);
|
link.setInlineEntity(expandEntity);
|
||||||
link.setHref(expandEntity.getId().toASCIIString());
|
link.setHref(expandEntity != null ? expandEntity.getId().toASCIIString() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the link - containing the expanded data - to the current entity
|
// set the link - containing the expanded data - to the current entity
|
||||||
|
|
|
@ -54,6 +54,7 @@ import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
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.UriResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
|
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;
|
||||||
|
@ -77,10 +78,61 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
this.serviceMetadata = 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 {
|
||||||
|
|
||||||
EdmEntityType responseEdmEntityType = null; // we'll need this to build the ContextURL
|
// The sample service supports only functions imports and entity sets.
|
||||||
|
// We do not care about bound functions and composable functions.
|
||||||
|
|
||||||
|
UriResource uriResource = uriInfo.getUriResourceParts().get(0);
|
||||||
|
|
||||||
|
if (uriResource instanceof UriResourceEntitySet) {
|
||||||
|
readEntityInternal(request, response, uriInfo, responseFormat);
|
||||||
|
} else if (uriResource instanceof UriResourceFunction) {
|
||||||
|
readFunctionImportInternal(request, response, uriInfo, responseFormat);
|
||||||
|
} else {
|
||||||
|
throw new ODataApplicationException("Only EntitySet is supported",
|
||||||
|
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFunctionImportInternal(final ODataRequest request, final ODataResponse response,
|
||||||
|
final UriInfo uriInfo, final ContentType responseFormat) throws ODataApplicationException, SerializerException {
|
||||||
|
|
||||||
|
// 1st step: Analyze the URI and fetch the entity returned by the function import
|
||||||
|
// Function Imports are always the first segment of the resource path
|
||||||
|
final UriResource firstSegment = uriInfo.getUriResourceParts().get(0);
|
||||||
|
|
||||||
|
if (!(firstSegment instanceof UriResourceFunction)) {
|
||||||
|
throw new ODataApplicationException("Not implemented", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),
|
||||||
|
Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
final UriResourceFunction uriResourceFunction = (UriResourceFunction) firstSegment;
|
||||||
|
final Entity entity = storage.readFunctionImportEntity(uriResourceFunction, serviceMetadata);
|
||||||
|
|
||||||
|
if (entity == null) {
|
||||||
|
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2nd step: Serialize the response entity
|
||||||
|
final EdmEntityType edmEntityType = (EdmEntityType) uriResourceFunction.getFunction().getReturnType().getType();
|
||||||
|
final ContextURL contextURL = ContextURL.with().type(edmEntityType).build();
|
||||||
|
final EntitySerializerOptions opts = EntitySerializerOptions.with().contextURL(contextURL).build();
|
||||||
|
final ODataSerializer serializer = odata.createSerializer(responseFormat);
|
||||||
|
final SerializerResult serializerResult = serializer.entity(serviceMetadata, edmEntityType, entity, opts);
|
||||||
|
|
||||||
|
// 3rd configure the response object
|
||||||
|
response.setContent(serializerResult.getContent());
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readEntityInternal(ODataRequest request, ODataResponse response, UriInfo uriInfo,
|
||||||
|
ContentType responseFormat)
|
||||||
|
throws ODataApplicationException, SerializerException {
|
||||||
|
|
||||||
|
EdmEntityType responseEdmEntityType = null; // we'll need this to build the ContextURL
|
||||||
Entity responseEntity = null; // required for serialization of the response body
|
Entity responseEntity = null; // required for serialization of the response body
|
||||||
EdmEntitySet responseEdmEntitySet = null; // we need this for building the contextUrl
|
EdmEntitySet responseEdmEntitySet = null; // we need this for building the contextUrl
|
||||||
|
|
||||||
|
@ -141,123 +193,122 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. apply system query options
|
// 3. apply system query options
|
||||||
|
|
||||||
// handle $select
|
// handle $select
|
||||||
SelectOption selectOption = uriInfo.getSelectOption();
|
SelectOption selectOption = uriInfo.getSelectOption();
|
||||||
// in our example, we don't have performance issues, so we can rely upon the handling in the Olingo lib
|
// 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
|
// nothing else to be done
|
||||||
|
|
||||||
// handle $expand
|
// handle $expand
|
||||||
ExpandOption expandOption = uriInfo.getExpandOption();
|
ExpandOption expandOption = uriInfo.getExpandOption();
|
||||||
// in our example: http://localhost:8080/DemoService/DemoService.svc/Categories(1)/$expand=Products
|
// in our example: http://localhost:8080/DemoService/DemoService.svc/Categories(1)/$expand=Products
|
||||||
// or http://localhost:8080/DemoService/DemoService.svc/Products(1)?$expand=Category
|
// or http://localhost:8080/DemoService/DemoService.svc/Products(1)?$expand=Category
|
||||||
if(expandOption != null) {
|
if (expandOption != null) {
|
||||||
// retrieve the EdmNavigationProperty from the expand expression
|
// retrieve the EdmNavigationProperty from the expand expression
|
||||||
// Note: in our example, we have only one NavigationProperty, so we can directly access it
|
// Note: in our example, we have only one NavigationProperty, so we can directly access it
|
||||||
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 = responseEdmEntitySet.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 = responseEdmEntitySet.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// can be 'Category' or 'Products', no path supported
|
// can be 'Category' or 'Products', no path supported
|
||||||
UriResource expandUriResource = 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(expandUriResource instanceof UriResourceNavigation) {
|
if (expandUriResource instanceof UriResourceNavigation) {
|
||||||
edmNavigationProperty = ((UriResourceNavigation) expandUriResource).getProperty();
|
edmNavigationProperty = ((UriResourceNavigation) expandUriResource).getProperty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// can be 'Category' or 'Products', no path supported
|
// can be 'Category' or 'Products', no path supported
|
||||||
// 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(edmNavigationProperty != null) {
|
if (edmNavigationProperty != null) {
|
||||||
EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
|
EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
|
||||||
String navPropName = edmNavigationProperty.getName();
|
String navPropName = edmNavigationProperty.getName();
|
||||||
|
|
||||||
// build the inline data
|
// build the inline data
|
||||||
Link link = new Link();
|
Link link = new Link();
|
||||||
link.setTitle(navPropName);
|
link.setTitle(navPropName);
|
||||||
link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
|
link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
|
||||||
link.setRel(Constants.NS_ASSOCIATION_LINK_REL + navPropName);
|
link.setRel(Constants.NS_ASSOCIATION_LINK_REL + navPropName);
|
||||||
|
|
||||||
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 =
|
EntityCollection expandEntityCollection =
|
||||||
storage.getRelatedEntityCollection(responseEntity, expandEdmEntityType);
|
storage.getRelatedEntityCollection(responseEntity, expandEdmEntityType);
|
||||||
link.setInlineEntitySet(expandEntityCollection);
|
link.setInlineEntitySet(expandEntityCollection);
|
||||||
link.setHref(expandEntityCollection.getId().toASCIIString());
|
link.setHref(expandEntityCollection.getId().toASCIIString());
|
||||||
} 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(responseEntity, expandEdmEntityType);
|
Entity expandEntity = storage.getRelatedEntity(responseEntity, expandEdmEntityType);
|
||||||
link.setInlineEntity(expandEntity);
|
link.setInlineEntity(expandEntity);
|
||||||
link.setHref(expandEntity.getId().toASCIIString());
|
link.setHref(expandEntity.getId().toASCIIString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the link - containing the expanded data - to the current entity
|
// set the link - containing the expanded data - to the current entity
|
||||||
responseEntity.getNavigationLinks().add(link);
|
responseEntity.getNavigationLinks().add(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4. serialize
|
||||||
|
EdmEntityType edmEntityType = responseEdmEntitySet.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(responseEdmEntitySet)
|
||||||
|
.selectList(selectList)
|
||||||
|
.suffix(Suffix.ENTITY).build();
|
||||||
|
|
||||||
// 4. serialize
|
// make sure that $expand and $select are considered by the serializer
|
||||||
EdmEntityType edmEntityType = responseEdmEntitySet.getEntityType();
|
// adding the selectOption to the serializerOpts will actually tell the lib to do the job
|
||||||
// we need the property names of the $select, in order to build the context URL
|
EntitySerializerOptions opts = EntitySerializerOptions.with()
|
||||||
String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType, expandOption, selectOption);
|
.contextURL(contextUrl)
|
||||||
ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet)
|
.select(selectOption)
|
||||||
.selectList(selectList)
|
.expand(expandOption)
|
||||||
.suffix(Suffix.ENTITY).build();
|
.build();
|
||||||
|
|
||||||
// make sure that $expand and $select are considered by the serializer
|
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
|
||||||
// adding the selectOption to the serializerOpts will actually tell the lib to do the job
|
SerializerResult serializerResult = serializer.entity(serviceMetadata, edmEntityType, responseEntity, opts);
|
||||||
EntitySerializerOptions opts = EntitySerializerOptions.with()
|
|
||||||
.contextURL(contextUrl)
|
|
||||||
.select(selectOption)
|
|
||||||
.expand(expandOption)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
|
// 5. configure the response object
|
||||||
SerializerResult serializerResult = serializer.entity(serviceMetadata, edmEntityType, responseEntity, opts);
|
response.setContent(serializerResult.getContent());
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||||
|
}
|
||||||
|
|
||||||
// 5. configure the response object
|
/*
|
||||||
response.setContent(serializerResult.getContent());
|
|
||||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Example request:
|
* Example request:
|
||||||
*
|
*
|
||||||
* POST URL: http://localhost:8080/DemoService/DemoService.svc/Products
|
* POST URL: http://localhost:8080/DemoService/DemoService.svc/Products
|
||||||
* Header: Content-Type: application/json; odata.metadata=minimal
|
* Header: Content-Type: application/json; odata.metadata=minimal
|
||||||
* Request body:
|
* Request body:
|
||||||
{
|
* {
|
||||||
"ID":3,
|
* "ID":3,
|
||||||
"Name":"Ergo Screen",
|
* "Name":"Ergo Screen",
|
||||||
"Description":"17 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"
|
* "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 {
|
||||||
|
|
||||||
// 1. Retrieve the entity type from the URI
|
// 1. Retrieve the entity type from the URI
|
||||||
EdmEntitySet edmEntitySet = Util.getEdmEntitySet(uriInfo);
|
EdmEntitySet edmEntitySet = Util.getEdmEntitySet(uriInfo);
|
||||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
// 2. create the data in backend
|
// 2. create the data in backend
|
||||||
// 2.1. retrieve the payload from the POST request for the entity to create and deserialize it
|
// 2.1. retrieve the payload from the POST request for the entity to create and deserialize it
|
||||||
InputStream requestInputStream = request.getBody();
|
InputStream requestInputStream = request.getBody();
|
||||||
ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
|
ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
|
||||||
|
@ -265,34 +316,35 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
Entity requestEntity = result.getEntity();
|
Entity requestEntity = result.getEntity();
|
||||||
// 2.2 do the creation in backend, which returns the newly created entity
|
// 2.2 do the creation in backend, which returns the newly created entity
|
||||||
Entity createdEntity = storage.createEntityData(edmEntitySet, requestEntity);
|
Entity createdEntity = storage.createEntityData(edmEntitySet, requestEntity);
|
||||||
|
|
||||||
// 3. serialize the response (we have to return the created entity)
|
// 3. serialize the response (we have to return the created entity)
|
||||||
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
|
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
|
||||||
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build(); // expand and select currently not supported
|
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build(); // expand and
|
||||||
|
// select currently
|
||||||
|
// not supported
|
||||||
|
|
||||||
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
|
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
|
||||||
SerializerResult serializedResponse = serializer.entity(serviceMetadata, edmEntityType, createdEntity, options);
|
SerializerResult serializedResponse = serializer.entity(serviceMetadata, edmEntityType, createdEntity, options);
|
||||||
|
|
||||||
//4. configure the response object
|
// 4. configure the response object
|
||||||
response.setContent(serializedResponse.getContent());
|
response.setContent(serializedResponse.getContent());
|
||||||
response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
|
response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
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 {
|
||||||
|
|
||||||
// 1. Retrieve the entity set which belongs to the requested entity
|
// 1. Retrieve the entity set which belongs to the requested entity
|
||||||
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||||
// Note: only in our example we can assume that the first segment is the EntitySet
|
// Note: only in our example we can assume that the first segment is the EntitySet
|
||||||
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
|
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
|
||||||
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
||||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||||
|
|
||||||
// 2. update the data in backend
|
// 2. update the data in backend
|
||||||
// 2.1. retrieve the payload from the PUT request for the entity to be updated
|
// 2.1. retrieve the payload from the PUT request for the entity to be updated
|
||||||
InputStream requestInputStream = request.getBody();
|
InputStream requestInputStream = request.getBody();
|
||||||
ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
|
ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
|
||||||
DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType);
|
DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType);
|
||||||
|
@ -302,26 +354,25 @@ public class DemoEntityProcessor implements EntityProcessor {
|
||||||
// Note that this updateEntity()-method is invoked for both PUT or PATCH operations
|
// Note that this updateEntity()-method is invoked for both PUT or PATCH operations
|
||||||
HttpMethod httpMethod = request.getMethod();
|
HttpMethod httpMethod = request.getMethod();
|
||||||
storage.updateEntityData(edmEntitySet, keyPredicates, requestEntity, httpMethod);
|
storage.updateEntityData(edmEntitySet, keyPredicates, requestEntity, httpMethod);
|
||||||
|
|
||||||
//3. configure the response object
|
// 3. configure the response object
|
||||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
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 {
|
||||||
|
|
||||||
// 1. Retrieve the entity set which belongs to the requested entity
|
// 1. Retrieve the entity set which belongs to the requested entity
|
||||||
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||||
// Note: only in our example we can assume that the first segment is the EntitySet
|
// Note: only in our example we can assume that the first segment is the EntitySet
|
||||||
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
|
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
|
||||||
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
||||||
|
|
||||||
// 2. delete the data in backend
|
// 2. delete the data in backend
|
||||||
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
|
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
|
||||||
storage.deleteEntityData(edmEntitySet, keyPredicates);
|
storage.deleteEntityData(edmEntitySet, keyPredicates);
|
||||||
|
|
||||||
//3. configure the response object
|
// 3. configure the response object
|
||||||
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import myservice.mynamespace.data.Storage;
|
import myservice.mynamespace.data.Storage;
|
||||||
|
import myservice.mynamespace.service.DemoActionProcessor;
|
||||||
import myservice.mynamespace.service.DemoEdmProvider;
|
import myservice.mynamespace.service.DemoEdmProvider;
|
||||||
import myservice.mynamespace.service.DemoEntityCollectionProcessor;
|
import myservice.mynamespace.service.DemoEntityCollectionProcessor;
|
||||||
import myservice.mynamespace.service.DemoEntityProcessor;
|
import myservice.mynamespace.service.DemoEntityProcessor;
|
||||||
|
@ -63,6 +64,7 @@ public class DemoServlet extends HttpServlet {
|
||||||
handler.register(new DemoEntityCollectionProcessor(storage));
|
handler.register(new DemoEntityCollectionProcessor(storage));
|
||||||
handler.register(new DemoEntityProcessor(storage));
|
handler.register(new DemoEntityProcessor(storage));
|
||||||
handler.register(new DemoPrimitiveProcessor(storage));
|
handler.register(new DemoPrimitiveProcessor(storage));
|
||||||
|
handler.register(new DemoActionProcessor(storage));
|
||||||
|
|
||||||
// let the handler do the work
|
// let the handler do the work
|
||||||
handler.process(req, resp);
|
handler.process(req, resp);
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class Storage {
|
||||||
resetDataSet(Integer.MAX_VALUE);
|
resetDataSet(Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetDataSet(final Integer amount) {
|
public void resetDataSet(final int amount) {
|
||||||
// Replace the old lists with empty ones
|
// Replace the old lists with empty ones
|
||||||
productList = new ArrayList<Entity>();
|
productList = new ArrayList<Entity>();
|
||||||
categoryList = new ArrayList<Entity>();
|
categoryList = new ArrayList<Entity>();
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class DemoActionProcessor implements ActionVoidProcessor {
|
||||||
.get(0)).getAction();
|
.get(0)).getAction();
|
||||||
|
|
||||||
// 2nd Deserialize the parameter
|
// 2nd Deserialize the parameter
|
||||||
// In our case there is only one action. So we can be sure that parameter has been provided by the client
|
// In our case there is only one action. So we can be sure that parameter "Amount" has been provided by the client
|
||||||
if (requestFormat == null) {
|
if (requestFormat == null) {
|
||||||
throw new ODataApplicationException("The content type has not been set in the request.",
|
throw new ODataApplicationException("The content type has not been set in the request.",
|
||||||
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||||
|
|
Loading…
Reference in New Issue