[OLINGO-713] Switched tutorials to release snapshot. Started to create a merged version of all tutorials

This commit is contained in:
Christian Holzer 2015-09-03 15:31:54 +02:00
parent 4ff196cbe7
commit 170d561c04
63 changed files with 3052 additions and 200 deletions

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.group.id</groupId>
<artifactId>DemoService</artifactId>
<packaging>war</packaging>
<version>4.0.0</version>
<name>${project.artifactId} Webapp</name>
<build>
<finalName>DemoService</finalName>
</build>
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${javax.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-server-api</artifactId>
<version>${odata.version}</version>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-server-core</artifactId>
<version>${odata.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-commons-api</artifactId>
<version>${odata.version}</version>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-commons-core</artifactId>
<version>${odata.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,252 @@
/*
* 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.data;
import java.util.ArrayList;
import java.util.List;
import myservice.mynamespace.service.DemoEdmProvider;
import myservice.mynamespace.util.Util;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.server.api.uri.UriParameter;
public class Storage {
// represent our database
private List<Entity> productList;
private List<Entity> categoryList;
public Storage() {
productList = new ArrayList<Entity>();
categoryList = new ArrayList<Entity>();
// creating some sample data
initProductSampleData();
initCategorySampleData();
}
/* PUBLIC FACADE */
public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet) {
EntityCollection entitySet = null;
if (edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)) {
entitySet = getProducts();
} else if (edmEntitySet.getName().equals(DemoEdmProvider.ES_CATEGORIES_NAME)) {
entitySet = getCategories();
}
return entitySet;
}
public Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams) {
Entity entity = null;
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
entity = getProduct(edmEntityType, keyParams);
} else if (edmEntityType.getName().equals(DemoEdmProvider.ET_CATEGORY_NAME)) {
entity = getCategory(edmEntityType, keyParams);
}
return entity;
}
// Navigation
public Entity getRelatedEntity(Entity entity, EdmEntityType relatedEntityType) {
EntityCollection collection = getRelatedEntityCollection(entity, relatedEntityType);
if (collection.getEntities().isEmpty()) {
return null;
}
return collection.getEntities().get(0);
}
public Entity getRelatedEntity(Entity entity, EdmEntityType relatedEntityType, List<UriParameter> keyPredicates) {
EntityCollection relatedEntities = getRelatedEntityCollection(entity, relatedEntityType);
return Util.findEntity(relatedEntityType, relatedEntities, keyPredicates);
}
public EntityCollection getRelatedEntityCollection(Entity sourceEntity, EdmEntityType targetEntityType) {
EntityCollection navigationTargetEntityCollection = new EntityCollection();
FullQualifiedName relatedEntityFqn = targetEntityType.getFullQualifiedName();
String sourceEntityFqn = sourceEntity.getType();
if (sourceEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString())
&& relatedEntityFqn.equals(DemoEdmProvider.ET_CATEGORY_FQN)) {
// relation Products->Category (result all categories)
int productID = (Integer) sourceEntity.getProperty("ID").getValue();
if (productID == 1 || productID == 2) {
navigationTargetEntityCollection.getEntities().add(categoryList.get(0));
} else if (productID == 3 || productID == 4) {
navigationTargetEntityCollection.getEntities().add(categoryList.get(1));
} else if (productID == 5 || productID == 6) {
navigationTargetEntityCollection.getEntities().add(categoryList.get(2));
}
} else if (sourceEntityFqn.equals(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString())
&& relatedEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN)) {
// relation Category->Products (result all products)
int categoryID = (Integer) sourceEntity.getProperty("ID").getValue();
if (categoryID == 1) {
// the first 2 products are notebooks
navigationTargetEntityCollection.getEntities().addAll(productList.subList(0, 2));
} else if (categoryID == 2) {
// the next 2 products are organizers
navigationTargetEntityCollection.getEntities().addAll(productList.subList(2, 4));
} else if (categoryID == 3) {
// the first 2 products are monitors
navigationTargetEntityCollection.getEntities().addAll(productList.subList(4, 6));
}
}
if (navigationTargetEntityCollection.getEntities().isEmpty()) {
return null;
}
return navigationTargetEntityCollection;
}
/* INTERNAL */
private EntityCollection getProducts() {
EntityCollection retEntitySet = new EntityCollection();
for (Entity productEntity : this.productList) {
retEntitySet.getEntities().add(productEntity);
}
return retEntitySet;
}
private Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams) {
// the list of entities at runtime
EntityCollection entityCollection = getProducts();
/* generic approach to find the requested entity */
return Util.findEntity(edmEntityType, entityCollection, keyParams);
}
private EntityCollection getCategories() {
EntityCollection entitySet = new EntityCollection();
for (Entity categoryEntity : this.categoryList) {
entitySet.getEntities().add(categoryEntity);
}
return entitySet;
}
private Entity getCategory(EdmEntityType edmEntityType, List<UriParameter> keyParams) {
// the list of entities at runtime
EntityCollection entitySet = getCategories();
/* generic approach to find the requested entity */
return Util.findEntity(edmEntityType, entitySet, keyParams);
}
/* HELPER */
private void initProductSampleData() {
Entity entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"));
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
"Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"));
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
productList.add(entity);
entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Professional 17"));
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
"Notebook Professional, 2.8GHz - 15 XGA - 8GB DDR3 RAM - 500GB"));
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
productList.add(entity);
entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"));
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
"Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"));
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
productList.add(entity);
entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 4));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Comfort Easy"));
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
"32 GB Digital Assitant with high-resolution color screen"));
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
productList.add(entity);
entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 5));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"));
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
"19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"));
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
productList.add(entity);
entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 6));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Flat Basic"));
entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
"Optimum Hi-Resolution max. 1600 x 1200 @ 85Hz, Dot Pitch: 0.24mm"));
entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
productList.add(entity);
}
private void initCategorySampleData() {
Entity entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebooks"));
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
categoryList.add(entity);
entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Organizers"));
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
categoryList.add(entity);
entity = new Entity();
entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3));
entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Monitors"));
entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
categoryList.add(entity);
}
}

View File

@ -0,0 +1,210 @@
/*
* 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.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
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.CsdlEntityContainer;
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.CsdlEntityType;
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.CsdlProperty;
import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
public class DemoEdmProvider extends CsdlAbstractEdmProvider {
// Service Namespace
public static final String NAMESPACE = "OData.Demo";
// EDM Container
public static final String CONTAINER_NAME = "Container";
public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME);
// Entity Types Names
public static final String ET_PRODUCT_NAME = "Product";
public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME);
public static final String ET_CATEGORY_NAME = "Category";
public static final FullQualifiedName ET_CATEGORY_FQN = new FullQualifiedName(NAMESPACE, ET_CATEGORY_NAME);
// Entity Set Names
public static final String ES_PRODUCTS_NAME = "Products";
public static final String ES_CATEGORIES_NAME = "Categories";
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for each EntityType that are configured in the Schema
CsdlEntityType entityType = null;
if (entityTypeName.equals(ET_PRODUCT_FQN)) {
// create EntityType properties
CsdlProperty id = new CsdlProperty().setName("ID")
.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
CsdlProperty name = new CsdlProperty().setName("Name")
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
CsdlProperty description = new CsdlProperty().setName("Description")
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
// create PropertyRef for Key element
CsdlPropertyRef propertyRef = new CsdlPropertyRef();
propertyRef.setName("ID");
// navigation property: many-to-one, null not allowed (product must have a category)
CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName("Category")
.setType(ET_CATEGORY_FQN).setNullable(false).setPartner("Products");
List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
navPropList.add(navProp);
// configure EntityType
entityType = new CsdlEntityType();
entityType.setName(ET_PRODUCT_NAME);
entityType.setProperties(Arrays.asList(id, name, description));
entityType.setKey(Arrays.asList(propertyRef));
entityType.setNavigationProperties(navPropList);
} else if (entityTypeName.equals(ET_CATEGORY_FQN)) {
// create EntityType properties
CsdlProperty id = new CsdlProperty().setName("ID")
.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
CsdlProperty name = new CsdlProperty().setName("Name")
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
// create PropertyRef for Key element
CsdlPropertyRef propertyRef = new CsdlPropertyRef();
propertyRef.setName("ID");
// navigation property: one-to-many
CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName("Products")
.setType(ET_PRODUCT_FQN).setCollection(true).setPartner("Category");
List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
navPropList.add(navProp);
// configure EntityType
entityType = new CsdlEntityType();
entityType.setName(ET_CATEGORY_NAME);
entityType.setProperties(Arrays.asList(id, name));
entityType.setKey(Arrays.asList(propertyRef));
entityType.setNavigationProperties(navPropList);
}
return entityType;
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
CsdlEntitySet entitySet = null;
if (entityContainer.equals(CONTAINER)) {
if (entitySetName.equals(ES_PRODUCTS_NAME)) {
entitySet = new CsdlEntitySet();
entitySet.setName(ES_PRODUCTS_NAME);
entitySet.setType(ET_PRODUCT_FQN);
// navigation
CsdlNavigationPropertyBinding navPropBinding = new CsdlNavigationPropertyBinding();
navPropBinding.setTarget("Categories"); // the target entity set, where the navigation property points to
navPropBinding.setPath("Category"); // the path from entity type to navigation property
List<CsdlNavigationPropertyBinding> navPropBindingList = new ArrayList<CsdlNavigationPropertyBinding>();
navPropBindingList.add(navPropBinding);
entitySet.setNavigationPropertyBindings(navPropBindingList);
} else if (entitySetName.equals(ES_CATEGORIES_NAME)) {
entitySet = new CsdlEntitySet();
entitySet.setName(ES_CATEGORIES_NAME);
entitySet.setType(ET_CATEGORY_FQN);
// navigation
CsdlNavigationPropertyBinding navPropBinding = new CsdlNavigationPropertyBinding();
navPropBinding.setTarget("Products"); // the target entity set, where the navigation property points to
navPropBinding.setPath("Products"); // the path from entity type to navigation property
List<CsdlNavigationPropertyBinding> navPropBindingList = new ArrayList<CsdlNavigationPropertyBinding>();
navPropBindingList.add(navPropBinding);
entitySet.setNavigationPropertyBindings(navPropBindingList);
}
}
return entitySet;
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document at
// e.g. http://localhost:8080/DemoService/DemoService.svc
if (entityContainerName == null || entityContainerName.equals(CONTAINER)) {
CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
entityContainerInfo.setContainerName(CONTAINER);
return entityContainerInfo;
}
return null;
}
@Override
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
schema.setNamespace(NAMESPACE);
// add EntityTypes
List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
entityTypes.add(getEntityType(ET_PRODUCT_FQN));
entityTypes.add(getEntityType(ET_CATEGORY_FQN));
schema.setEntityTypes(entityTypes);
// add EntityContainer
schema.setEntityContainer(getEntityContainer());
// finally
List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
schemas.add(schema);
return schemas;
}
@Override
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
entitySets.add(getEntitySet(CONTAINER, ES_CATEGORIES_NAME));
// create EntityContainer
CsdlEntityContainer entityContainer = new CsdlEntityContainer();
entityContainer.setName(CONTAINER_NAME);
entityContainer.setEntitySets(entitySets);
return entityContainer;
}
}

View File

@ -0,0 +1,356 @@
/*
* 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.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import myservice.mynamespace.data.Storage;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
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.ExpandItem;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.FilterOption;
import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.api.uri.queryoption.SkipOption;
import org.apache.olingo.server.api.uri.queryoption.TopOption;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
import org.apache.olingo.server.api.uri.queryoption.expression.Member;
public class DemoEntityCollectionProcessor implements EntityCollectionProcessor {
private OData odata;
private ServiceMetadata serviceMetadata;
private Storage storage;
public DemoEntityCollectionProcessor(Storage storage) {
this.storage = storage;
}
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
public void readEntityCollection(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();
// in our example, the first segment is the EntitySet
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
// 2nd: fetch the data from backend for this requested EntitySetName and deliver as EntitySet
EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet);
EntityCollection modifiedEntityCollection = new EntityCollection();
List<Entity> modifiedEntityList = new ArrayList<Entity>();
modifiedEntityList.addAll(entityCollection.getEntities());
// 3rd: Apply system query option
// The system query options have to be applied in a defined order
// 3.1.) $filter
modifiedEntityList = applyFilterQueryOption(modifiedEntityList, uriInfo.getFilterOption());
// 3.2.) $orderby
modifiedEntityList = applyOrderQueryOption(modifiedEntityList, uriInfo.getOrderByOption());
// 3.3.) $count
modifiedEntityList = applyCountQueryOption(modifiedEntityCollection, modifiedEntityList, uriInfo.getCountOption());
// 3.4.) $skip
modifiedEntityList = applySkipQueryOption(modifiedEntityList, uriInfo.getSkipOption());
// 3.5.) $top
modifiedEntityList = applyTopQueryOption(modifiedEntityList, uriInfo.getTopOption());
// 3.6.) Server driven paging (not part of this tutorial)
// 3.7.) $expand
modifiedEntityList = applyExpandQueryOption(modifiedEntityCollection, modifiedEntityList, edmEntitySet,
uriInfo.getExpandOption());
// 3.8.) $select
SelectOption selectOption = uriInfo.getSelectOption();
// Set the (may) modified entityList to the new entity collection
modifiedEntityCollection.getEntities().addAll(modifiedEntityList);
// 4th: create a serializer based on the requested format (json)
ODataSerializer serializer = odata.createSerializer(responseFormat);
// we need the property names of the $select, in order to build the context URL
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
String selectList = odata.createUriHelper()
.buildContextURLSelectList(edmEntityType, uriInfo.getExpandOption(), selectOption);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).selectList(selectList).build();
// adding the selectOption to the serializerOpts will actually tell the lib to do the job
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with()
.contextURL(contextUrl)
.count(uriInfo.getCountOption())
.select(selectOption)
.expand(uriInfo.getExpandOption())
.build();
// and serialize the content: transform from the EntitySet object to InputStream
SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType,
modifiedEntityCollection, opts);
InputStream serializedContent = serializerResult.getContent();
// 5th: configure the response object: set the body, headers and status code
response.setContent(serializedContent);
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
private List<Entity> applyExpandQueryOption(EntityCollection entityCollection, List<Entity> modifiedEntityList,
EdmEntitySet edmEntitySet, ExpandOption expandOption) {
// in our example: http://localhost:8080/DemoService/DemoService.svc/Categories/$expand=Products
// or http://localhost:8080/DemoService/DemoService.svc/Products?$expand=Category
if (expandOption != null) {
// retrieve the EdmNavigationProperty from the expand expression
// Note: in our example, we have only one NavigationProperty, so we can directly access it
EdmNavigationProperty edmNavigationProperty = null;
ExpandItem expandItem = expandOption.getExpandItems().get(0);
if (expandItem.isStar()) {
List<EdmNavigationPropertyBinding> bindings = edmEntitySet.getNavigationPropertyBindings();
// we know that there are navigation bindings
// however normally in this case a check if navigation bindings exists is done
if (!bindings.isEmpty()) {
// can in our case only be 'Category' or 'Products', so we can take the first
EdmNavigationPropertyBinding binding = bindings.get(0);
EdmElement property = edmEntitySet.getEntityType().getProperty(binding.getPath());
// we don't need to handle error cases, as it is done in the Olingo library
if (property instanceof EdmNavigationProperty) {
edmNavigationProperty = (EdmNavigationProperty) property;
}
}
} else {
// can be 'Category' or 'Products', no path supported
UriResource uriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
// we don't need to handle error cases, as it is done in the Olingo library
if (uriResource instanceof UriResourceNavigation) {
edmNavigationProperty = ((UriResourceNavigation) uriResource).getProperty();
}
}
// can be 'Category' or 'Products', no path supported
// we don't need to handle error cases, as it is done in the Olingo library
if (edmNavigationProperty != null) {
String navPropName = edmNavigationProperty.getName();
EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
for (Entity entity : modifiedEntityList) {
Link link = new Link();
link.setTitle(navPropName);
link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
if (edmNavigationProperty.isCollection()) { // in case of Categories/$expand=Products
// fetch the data for the $expand (to-many navigation) from backend
EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(entity, expandEdmEntityType);
link.setInlineEntitySet(expandEntityCollection);
} else { // in case of Products?$expand=Category
// fetch the data for the $expand (to-one navigation) from backend
// here we get the data for the expand
Entity expandEntity = storage.getRelatedEntity(entity, expandEdmEntityType);
link.setInlineEntity(expandEntity);
}
// set the link - containing the expanded data - to the current entity
entity.getNavigationLinks().add(link);
}
}
}
return modifiedEntityList;
}
private List<Entity> applyTopQueryOption(List<Entity> entityList, TopOption topOption)
throws ODataApplicationException {
if (topOption != null) {
int topNumber = topOption.getValue();
if (topNumber >= 0) {
if(topNumber <= entityList.size()) {
entityList = entityList.subList(0, topNumber);
} // else the client has requested more entities than available => return what we have
} else {
throw new ODataApplicationException("Invalid value for $top", HttpStatusCode.BAD_REQUEST.getStatusCode(),
Locale.ROOT);
}
}
return entityList;
}
private List<Entity> applySkipQueryOption(List<Entity> entityList, SkipOption skipOption)
throws ODataApplicationException {
if (skipOption != null) {
int skipNumber = skipOption.getValue();
if (skipNumber >= 0) {
if(skipNumber <= entityList.size()) {
entityList = entityList.subList(skipNumber, entityList.size());
} else {
// The client skipped all entities
entityList.clear();
}
} else {
throw new ODataApplicationException("Invalid value for $skip", HttpStatusCode.BAD_REQUEST.getStatusCode(),
Locale.ROOT);
}
}
return entityList;
}
private List<Entity> applyCountQueryOption(EntityCollection entityCollection, List<Entity> modifiedEntityList,
CountOption countOption) {
// handle $count: always return the original number of entities, without considering $top and $skip
if (countOption != null) {
boolean isCount = countOption.getValue();
if (isCount) {
entityCollection.setCount(modifiedEntityList.size());
}
}
return modifiedEntityList;
}
private List<Entity> applyOrderQueryOption(List<Entity> entityList, OrderByOption orderByOption) {
if (orderByOption != null) {
List<OrderByItem> orderItemList = orderByOption.getOrders();
final OrderByItem orderByItem = orderItemList.get(0); // in our example we support only one
Expression expression = orderByItem.getExpression();
if (expression instanceof Member) {
UriInfoResource resourcePath = ((Member) expression).getResourcePath();
UriResource uriResource = resourcePath.getUriResourceParts().get(0);
if (uriResource instanceof UriResourcePrimitiveProperty) {
EdmProperty edmProperty = ((UriResourcePrimitiveProperty) uriResource).getProperty();
final String sortPropertyName = edmProperty.getName();
// do the sorting for the list of entities
Collections.sort(entityList, new Comparator<Entity>() {
// we delegate the sorting to the native sorter of Integer and String
public int compare(Entity entity1, Entity entity2) {
int compareResult = 0;
if (sortPropertyName.equals("ID")) {
Integer integer1 = (Integer) entity1.getProperty(sortPropertyName).getValue();
Integer integer2 = (Integer) entity2.getProperty(sortPropertyName).getValue();
compareResult = integer1.compareTo(integer2);
} else {
String propertyValue1 = (String) entity1.getProperty(sortPropertyName).getValue();
String propertyValue2 = (String) entity2.getProperty(sortPropertyName).getValue();
compareResult = propertyValue1.compareTo(propertyValue2);
}
// if 'desc' is specified in the URI, change the order of the list
if (orderByItem.isDescending()) {
return -compareResult; // just convert the result to negative value to change the order
}
return compareResult;
}
});
}
}
}
return entityList;
}
private List<Entity> applyFilterQueryOption(List<Entity> entityList, FilterOption filterOption)
throws ODataApplicationException {
if (filterOption != null) {
try {
Iterator<Entity> entityIterator = entityList.iterator();
// Evaluate the expression for each entity
// If the expression is evaluated to "true", keep the entity otherwise remove it from the entityList
while (entityIterator.hasNext()) {
// To evaluate the the expression, create an instance of the Filter Expression Visitor and pass
// the current entity to the constructor
Entity currentEntity = entityIterator.next();
Expression filterExpression = filterOption.getExpression();
FilterExpressionVisitor expressionVisitor = new FilterExpressionVisitor(currentEntity);
// Start evaluating the expression
Object visitorResult = filterExpression.accept(expressionVisitor);
// The result of the filter expression must be of type Edm.Boolean
if (visitorResult instanceof Boolean) {
if (!Boolean.TRUE.equals(visitorResult)) {
// The expression evaluated to false (or null), so we have to remove the currentEntity from entityList
entityIterator.remove();
}
} else {
throw new ODataApplicationException("A filter expression must evaulate to type Edm.Boolean",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
}
} catch (ExpressionVisitException e) {
throw new ODataApplicationException("Exception in filter evaluation",
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH);
}
}
return entityList;
}
}

View File

@ -0,0 +1,202 @@
/*
* 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.List;
import java.util.Locale;
import myservice.mynamespace.data.Storage;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.processor.EntityProcessor;
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
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.SelectOption;
public class DemoEntityProcessor implements EntityProcessor {
private OData odata;
private ServiceMetadata srvMetadata;
private Storage storage;
public DemoEntityProcessor(Storage storage) {
this.storage = storage;
}
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.srvMetadata = serviceMetadata;
}
public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
throws ODataApplicationException, SerializerException {
// 1. retrieve the Entity Type
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
// Note: only in our example we can assume that the first segment is the EntitySet
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
// 2. retrieve the data from backend
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
// 3. apply system query options
// handle $select
SelectOption selectOption = uriInfo.getSelectOption();
// in our example, we don't have performance issues, so we can rely upon the handling in the Olingo lib
// nothing else to be done
// handle $expand
ExpandOption expandOption = uriInfo.getExpandOption();
// in our example: http://localhost:8080/DemoService/DemoService.svc/Categories(1)/$expand=Products
// or http://localhost:8080/DemoService/DemoService.svc/Products(1)?$expand=Category
if(expandOption != null) {
// retrieve the EdmNavigationProperty from the expand expression
// Note: in our example, we have only one NavigationProperty, so we can directly access it
EdmNavigationProperty edmNavigationProperty = null;
ExpandItem expandItem = expandOption.getExpandItems().get(0);
if(expandItem.isStar()) {
List<EdmNavigationPropertyBinding> bindings = edmEntitySet.getNavigationPropertyBindings();
// we know that there are navigation bindings
// however normally in this case a check if navigation bindings exists is done
if(!bindings.isEmpty()) {
// can in our case only be 'Category' or 'Products', so we can take the first
EdmNavigationPropertyBinding binding = bindings.get(0);
EdmElement property = edmEntitySet.getEntityType().getProperty(binding.getPath());
// we don't need to handle error cases, as it is done in the Olingo library
if(property instanceof EdmNavigationProperty) {
edmNavigationProperty = (EdmNavigationProperty) property;
}
}
} else {
// can be 'Category' or 'Products', no path supported
UriResource uriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
// we don't need to handle error cases, as it is done in the Olingo library
if(uriResource instanceof UriResourceNavigation) {
edmNavigationProperty = ((UriResourceNavigation) uriResource).getProperty();
}
}
// can be 'Category' or 'Products', no path supported
// we don't need to handle error cases, as it is done in the Olingo library
if(edmNavigationProperty != null) {
EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
String navPropName = edmNavigationProperty.getName();
// build the inline data
Link link = new Link();
link.setTitle(navPropName);
link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
if(edmNavigationProperty.isCollection()){ // in case of Categories(1)/$expand=Products
// fetch the data for the $expand (to-many navigation) from backend
// here we get the data for the expand
EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(entity, expandEdmEntityType);
link.setInlineEntitySet(expandEntityCollection);
} else { // in case of Products(1)?$expand=Category
// fetch the data for the $expand (to-one navigation) from backend
// here we get the data for the expand
Entity expandEntity = storage.getRelatedEntity(entity, expandEdmEntityType);
link.setInlineEntity(expandEntity);
}
// set the link - containing the expanded data - to the current entity
entity.getNavigationLinks().add(link);
}
}
// 4. serialize
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
// we need the property names of the $select, in order to build the context URL
String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType, expandOption, selectOption);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet)
.selectList(selectList)
.suffix(Suffix.ENTITY).build();
// make sure that $expand and $select are considered by the serializer
// adding the selectOption to the serializerOpts will actually tell the lib to do the job
EntitySerializerOptions opts = EntitySerializerOptions.with()
.contextURL(contextUrl)
.select(selectOption)
.expand(expandOption)
.build();
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entity(srvMetadata, edmEntityType, entity, opts);
// 5. configure the response object
response.setContent(serializerResult.getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
/*
* These processor methods are not handled in this tutorial
*/
public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
ContentType requestFormat, ContentType responseFormat)
throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
ContentType requestFormat, ContentType responseFormat)
throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
throws ODataApplicationException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}

View File

@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -55,6 +54,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
private OData odata;
private Storage storage;
private ServiceMetadata serviceMetadata;
public DemoPrimitiveProcessor(Storage storage) {
this.storage = storage;
@ -62,6 +62,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
@ -87,7 +88,8 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();
// 1.2. retrieve the requested (Edm) property
UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1); // the last segment is the Property
// the last segment is the Property
UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1);
EdmProperty edmProperty = uriProperty.getProperty();
String edmPropertyName = edmProperty.getName();
// in our example, we know we have only primitive types in our model
@ -104,20 +106,20 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
// 2.2. retrieve the property data from the entity
Property property = entity.getProperty(edmPropertyName);
if (property == null) {
throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(),
Locale.ENGLISH);
}
// 3. serialize
Object value = property.getValue();
if (value != null) {
// 3.1. configure the serializer
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
// 3.2. serialize
SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
InputStream propertyStream = serializerResult.getContent();
//4. configure the response object
@ -136,12 +138,13 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
* These processor methods are not handled in this tutorial
* */
public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat)
throws ODataApplicationException, DeserializerException, SerializerException {
public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException {
public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo)
throws ODataApplicationException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}

View File

@ -25,6 +25,7 @@ import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
@ -33,6 +34,7 @@ import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKin
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
@ -72,24 +74,25 @@ public class FilterExpressionVisitor implements ExpressionVisitor<Object> {
}
@Override
public Object visitLiteral(String literal) throws ExpressionVisitException, ODataApplicationException {
public Object visitLiteral(Literal literal) throws ExpressionVisitException, ODataApplicationException {
// To keep this tutorial simple, our filter expression visitor supports only Edm.Int32 and Edm.String
// In real world scenarios it can be difficult to guess the type of an literal.
// We can be sure, that the literal is a valid OData literal because the URI Parser checks
// the lexicographical structure
// String literals start and end with an single quotation mark
if(literal.startsWith("'") && literal.endsWith("'")) {
String literalAsString = literal.getText();
if(literal.getType() instanceof EdmString) {
String stringLiteral = "";
if(literal.length() > 2) {
stringLiteral = literal.substring(1, literal.length() - 1);
if(literal.getText().length() > 2) {
stringLiteral = literalAsString.substring(1, literalAsString.length() - 1);
}
return stringLiteral;
} else {
// Try to convert the literal into an Java Integer
try {
return Integer.parseInt(literal);
return Integer.parseInt(literalAsString);
} catch(NumberFormatException e) {
throw new ODataApplicationException("Only Edm.Int32 and Edm.String literals are implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);

View File

@ -0,0 +1,149 @@
/*
* 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.util;
import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriParameter;
public class Util {
public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
List<UriParameter> keyParams) {
List<Entity> entityList = entitySet.getEntities();
// loop over all entities in order to find that one that matches
// all keys in request e.g. contacts(ContactID=1, CompanyID=1)
for (Entity entity : entityList) {
boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams);
if (foundEntity) {
return entity;
}
}
return null;
}
public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity rt_entity,
List<UriParameter> keyParams) {
// loop over all keys
for (final UriParameter key : keyParams) {
// key
String keyName = key.getName();
String keyText = key.getText();
// note: below line doesn't consider: keyProp can be part of a complexType in V4
// in such case, it would be required to access it via getKeyPropertyRef()
// but since this isn't the case in our model, we ignore it in our implementation
EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(keyName);
// Edm: we need this info for the comparison below
Boolean isNullable = edmKeyProperty.isNullable();
Integer maxLength = edmKeyProperty.getMaxLength();
Integer precision = edmKeyProperty.getPrecision();
Boolean isUnicode = edmKeyProperty.isUnicode();
Integer scale = edmKeyProperty.getScale();
// get the EdmType in order to compare
EdmType edmType = edmKeyProperty.getType();
// if(EdmType instanceof EdmPrimitiveType) // do we need this?
EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType;
// Runtime data: the value of the current entity
// don't need to check for null, this is done in FWK
Object valueObject = rt_entity.getProperty(keyName).getValue();
// TODO if the property is a complex type
// now need to compare the valueObject with the keyText String
// this is done using the type.valueToString
String valueAsString = null;
try {
valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable,
maxLength, precision, scale, isUnicode);
} catch (EdmPrimitiveTypeException e) {
return false; // TODO proper Exception handling
}
if (valueAsString == null) {
return false;
}
boolean matches = valueAsString.equals(keyText);
// if any of the key properties is not found in the entity, we don't need to search further
if (!matches) {
return false;
}
// if the given key value is found in the current entity, continue with the next key
}
return true;
}
/**
* Example:
* For the following navigation: DemoService.svc/Categories(1)/Products
* we need the EdmEntitySet for the navigation property "Products"
*
* This is defined as follows in the metadata:
* <code>
*
* <EntitySet Name="Categories" EntityType="OData.Demo.Category">
* <NavigationPropertyBinding Path="Products" Target="Products"/>
* </EntitySet>
* </code>
* The "Target" attribute specifies the target EntitySet
* Therefore we need the startEntitySet "Categories" in order to retrieve the target EntitySet "Products"
*/
public static EdmEntitySet getNavigationTargetEntitySet(EdmEntitySet startEntitySet,
EdmNavigationProperty edmNavigationProperty)
throws ODataApplicationException {
EdmEntitySet navigationTargetEntitySet = null;
String navPropName = edmNavigationProperty.getName();
EdmBindingTarget edmBindingTarget = startEntitySet.getRelatedBindingTarget(navPropName);
if (edmBindingTarget == null) {
throw new ODataApplicationException("Not supported.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
if (edmBindingTarget instanceof EdmEntitySet) {
navigationTargetEntitySet = (EdmEntitySet) edmBindingTarget;
} else {
throw new ODataApplicationException("Not supported.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
return navigationTargetEntitySet;
}
}

View File

@ -25,7 +25,7 @@
<groupId>my.group.id</groupId>
<artifactId>DemoService-Read</artifactId>
<packaging>war</packaging>
<version>0.0.1</version>
<version>4.0.0</version>
<name>${project.artifactId}-Webapp</name>
@ -35,7 +35,7 @@
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-beta-03</odata.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
@ -75,5 +75,11 @@
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -23,7 +23,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
@ -58,7 +57,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
@Override
public List<CsdlSchema> getSchemas() throws ODataException {
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
@ -81,7 +80,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for one of the EntityTypes that are configured in the Schema
if(entityTypeName.equals(ET_PRODUCT_FQN)){
@ -108,7 +107,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException {
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
if(entityContainer.equals(CONTAINER)){
if(entitySetName.equals(ES_PRODUCTS_NAME)){
@ -124,7 +123,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainer getEntityContainer() throws ODataException {
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
@ -139,7 +138,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException {
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document at e.g. http://localhost:8080/DemoService/DemoService.svc
if(entityContainerName == null || entityContainerName.equals(CONTAINER)){

View File

@ -28,7 +28,6 @@ import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -78,9 +77,8 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
EntityCollection entitySet = getData(edmEntitySet);
// 3rd: create a serializer based on the requested format (json)
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
// 4th: Now serialize the content: transform from the EntitySet object to InputStream
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();

View File

@ -1,31 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!-- 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. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.group.id</groupId>
<artifactId>DemoService-ReadEp</artifactId>
<packaging>war</packaging>
<version>0.0.1</version>
<version>4.0.0</version>
<name>${project.artifactId}-Webapp</name>
@ -35,7 +19,7 @@
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-beta-03</odata.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
@ -75,5 +59,12 @@
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -23,7 +23,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
@ -53,8 +52,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName)
throws ODataException {
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for one of the EntityTypes that are configured in the Schema
if(ET_PRODUCT_FQN.equals(entityTypeName)){
@ -81,8 +79,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer,
String entitySetName) throws ODataException {
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
if(entityContainer.equals(CONTAINER)){
if(entitySetName.equals(ES_PRODUCTS_NAME)){
CsdlEntitySet entitySet = new CsdlEntitySet();
@ -98,9 +95,9 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(
FullQualifiedName entityContainerName) throws ODataException {
// This method is invoked when displaying the service document at e.g. http://localhost:8080/DemoService/DemoService.svc
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document
// at e.g. http://localhost:8080/DemoService/DemoService.svc
if(entityContainerName == null || entityContainerName.equals(CONTAINER)){
CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
entityContainerInfo.setContainerName(CONTAINER);
@ -112,7 +109,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public List<CsdlSchema> getSchemas() throws ODataException {
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
schema.setNamespace(NAMESPACE);
@ -134,7 +131,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainer getEntityContainer() throws ODataException {
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));

View File

@ -28,7 +28,6 @@ import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -71,8 +70,7 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet);
// 3rd: create a serializer based on the requested format (json)
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
// and serialize the content: transform from the EntitySet object to InputStream
EdmEntityType edmEntityType = edmEntitySet.getEntityType();

View File

@ -29,7 +29,6 @@ import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -88,8 +87,7 @@ public class DemoEntityProcessor implements EntityProcessor {
// expand and select currently not supported
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options);
InputStream entityStream = serializerResult.getContent();

View File

@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -55,6 +54,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
private OData odata;
private Storage storage;
private ServiceMetadata serviceMetadata;
public DemoPrimitiveProcessor(Storage storage) {
this.storage = storage;
@ -62,7 +62,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
/*
@ -111,13 +111,12 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
Object value = property.getValue();
if (value != null) {
// 3.1. configure the serializer
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
// 3.2. serialize
SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
InputStream propertyStream = serializerResult.getContent();
//4. configure the response object

View File

@ -23,7 +23,6 @@ import java.util.Locale;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
@ -31,10 +30,7 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
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.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
public class Util {

View File

@ -25,7 +25,7 @@
<groupId>my.group.id</groupId>
<artifactId>DemoService-Write</artifactId>
<packaging>war</packaging>
<version>0.0.1</version>
<version>4.0.0</version>
<name>${project.artifactId}-Webapp</name>
@ -35,7 +35,7 @@
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-beta-03</odata.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
@ -75,5 +75,11 @@
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -23,7 +23,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
@ -58,7 +57,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
@Override
public List<CsdlSchema> getSchemas() throws ODataException {
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
@ -81,7 +80,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for one of the EntityTypes that are configured in the Schema
if(entityTypeName.equals(ET_PRODUCT_FQN)){
@ -111,7 +110,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException {
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
if(entityContainer.equals(CONTAINER)){
if(entitySetName.equals(ES_PRODUCTS_NAME)){
@ -128,7 +127,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
public CsdlEntityContainer getEntityContainer() throws ODataException {
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
@ -143,7 +142,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException {
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document at
// e.g. http://localhost:8080/DemoService/DemoService.svc

View File

@ -27,7 +27,6 @@ import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -75,8 +74,7 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
EntityCollection entitySet = storage.readEntitySetData(edmEntitySet);
// 3rd: create a serializer based on the requested format (json)
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
// and serialize the content: transform from the EntitySet object to InputStream
EdmEntityType edmEntityType = edmEntitySet.getEntityType();

View File

@ -29,7 +29,6 @@ import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
@ -87,8 +86,7 @@ public class DemoEntityProcessor implements EntityProcessor {
// expand and select currently not supported
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult result = serializer.entity(serviceMetadata, entityType, entity, options);
//4. configure the response object
@ -120,8 +118,7 @@ public class DemoEntityProcessor implements EntityProcessor {
// 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();
ODataFormat requestODataFormat = ODataFormat.fromContentType(requestFormat);
ODataDeserializer deserializer = this.odata.createDeserializer(requestODataFormat);
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
@ -131,8 +128,7 @@ public class DemoEntityProcessor implements EntityProcessor {
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build(); // expand and select currently not supported
ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult serializedResponse = serializer.entity(serviceMetadata, edmEntityType, createdEntity, options);
//4. configure the response object
@ -156,8 +152,7 @@ public class DemoEntityProcessor implements EntityProcessor {
// 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();
ODataFormat requestODataFormat = ODataFormat.fromContentType(requestFormat);
ODataDeserializer deserializer = this.odata.createDeserializer(requestODataFormat);
ODataDeserializer deserializer = this.odata.createDeserializer(requestFormat);
DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType);
Entity requestEntity = result.getEntity();
// 2.2 do the modification in backend

View File

@ -30,7 +30,6 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -54,6 +53,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
private OData odata;
private Storage storage;
private ServiceMetadata serviceMetadata;
public DemoPrimitiveProcessor(Storage storage) {
this.storage = storage;
@ -61,6 +61,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
/*
@ -111,13 +112,12 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
Object value = property.getValue();
if (value != null) {
// 3.1. configure the serializer
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
// 3.2. serialize
SerializerResult result = serializer.primitive(edmPropertyType, property, options);
SerializerResult result = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
//4. configure the response object
response.setContent(result.getContent());

View File

@ -25,7 +25,7 @@
<groupId>my.group.id</groupId>
<artifactId>DemoService-Navigation</artifactId>
<packaging>war</packaging>
<version>0.0.1</version>
<version>4.0.0</version>
<name>${project.artifactId}-Webapp</name>
@ -35,7 +35,7 @@
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-beta-03</odata.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
@ -76,5 +76,12 @@
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
@ -57,7 +56,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
public static final String ES_CATEGORIES_NAME = "Categories";
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for each EntityType that are configured in the Schema
CsdlEntityType entityType = null;
@ -118,7 +117,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException {
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
CsdlEntitySet entitySet = null;
@ -158,7 +157,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException {
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document at
// e.g. http://localhost:8080/DemoService/DemoService.svc
@ -172,7 +171,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public List<CsdlSchema> getSchemas() throws ODataException {
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
schema.setNamespace(NAMESPACE);
@ -194,7 +193,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainer getEntityContainer() throws ODataException {
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();

View File

@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -136,7 +135,7 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).build();
EdmEntityType edmEntityType = responseEdmEntitySet.getEntityType();
ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(responseFormat));
ODataSerializer serializer = odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entityCollection(this.srvMetadata, edmEntityType,
responseEntityCollection, opts);

View File

@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -145,8 +144,7 @@ public class DemoEntityProcessor implements EntityProcessor {
ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).suffix(Suffix.ENTITY).build();
EntitySerializerOptions opts = EntitySerializerOptions.with().contextURL(contextUrl).build();
ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entity(this.srvMetadata,
responseEdmEntityType, responseEntity, opts);

View File

@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -55,6 +54,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
private OData odata;
private Storage storage;
private ServiceMetadata serviceMetadata;
public DemoPrimitiveProcessor(Storage storage) {
this.storage = storage;
@ -62,6 +62,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
@ -114,13 +115,12 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
Object value = property.getValue();
if (value != null) {
// 3.1. configure the serializer
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
// 3.2. serialize
SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
InputStream propertyStream = serializerResult.getContent();
// 4. configure the response object

View File

@ -25,7 +25,7 @@
<groupId>my.group.id</groupId>
<artifactId>DemoService-QueryOptions-TCS</artifactId>
<packaging>war</packaging>
<version>0.0.1</version>
<version>4.0.0</version>
<name>${project.artifactId}-Webapp</name>
@ -35,7 +35,7 @@
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-beta-03</odata.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
@ -75,5 +75,11 @@
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -23,7 +23,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
@ -52,8 +51,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
public static final String ES_PRODUCTS_NAME = "Products";
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName)
throws ODataException {
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for one of the EntityTypes that are configured in the Schema
if (ET_PRODUCT_FQN.equals(entityTypeName)) {
@ -83,8 +81,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer,
String entitySetName) throws ODataException {
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
if (entityContainer.equals(CONTAINER)) {
if (entitySetName.equals(ES_PRODUCTS_NAME)) {
CsdlEntitySet entitySet = new CsdlEntitySet();
@ -100,8 +97,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(
FullQualifiedName entityContainerName) throws ODataException {
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document at
// e.g. http://localhost:8080/DemoService/DemoService.svc
if (entityContainerName == null || entityContainerName.equals(CONTAINER)) {
@ -115,7 +111,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public List<CsdlSchema> getSchemas() throws ODataException {
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
schema.setNamespace(NAMESPACE);
@ -137,7 +133,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainer getEntityContainer() throws ODataException {
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));

View File

@ -30,7 +30,6 @@ import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -121,8 +120,7 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
}
// 4th: create a serializer based on the requested format (json)
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
// and serialize the content: transform from the EntitySet object to InputStream
EdmEntityType edmEntityType = edmEntitySet.getEntityType();

View File

@ -29,7 +29,6 @@ import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -83,8 +82,7 @@ public class DemoEntityProcessor implements EntityProcessor {
// expand and select currently not supported
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options);
InputStream entityStream = serializerResult.getContent();

View File

@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -55,6 +54,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
private OData odata;
private Storage storage;
private ServiceMetadata serviceMetadata;
public DemoPrimitiveProcessor(Storage storage) {
this.storage = storage;
@ -62,7 +62,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
/*
@ -112,13 +112,12 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
Object value = property.getValue();
if (value != null) {
// 3.1. configure the serializer
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
// 3.2. serialize
SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
InputStream propertyStream = serializerResult.getContent();
//4. configure the response object

View File

@ -23,7 +23,6 @@ import java.util.Locale;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
@ -31,10 +30,7 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
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.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
public class Util {

View File

@ -25,7 +25,7 @@
<groupId>my.group.id</groupId>
<artifactId>DemoService-QueryOptions-ES</artifactId>
<packaging>war</packaging>
<version>0.0.1</version>
<version>4.0.0</version>
<name>${project.artifactId}-Webapp</name>
@ -35,7 +35,7 @@
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-beta-03</odata.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
@ -76,5 +76,11 @@
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
@ -57,7 +56,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
public static final String ES_CATEGORIES_NAME = "Categories";
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for each EntityType that are configured in the Schema
CsdlEntityType entityType = null;
@ -118,7 +117,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException {
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
CsdlEntitySet entitySet = null;
@ -158,7 +157,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException {
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document at
// e.g. http://localhost:8080/DemoService/DemoService.svc
@ -172,7 +171,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public List<CsdlSchema> getSchemas() throws ODataException {
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
schema.setNamespace(NAMESPACE);
@ -194,7 +193,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainer getEntityContainer() throws ODataException {
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();

View File

@ -33,7 +33,6 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -170,7 +169,7 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
.expand(expandOption)
.build();
ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(responseFormat));
ODataSerializer serializer = odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entityCollection(srvMetadata, edmEntityType, entityCollection, opts);
// 5th: configure the response object: set the body, headers and status code

View File

@ -35,7 +35,6 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -169,7 +168,7 @@ public class DemoEntityProcessor implements EntityProcessor {
.expand(expandOption)
.build();
ODataSerializer serializer = this.odata.createSerializer(ODataFormat.fromContentType(responseFormat));
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entity(srvMetadata, edmEntityType, entity, opts);
// 5. configure the response object

View File

@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -55,6 +54,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
private OData odata;
private Storage storage;
private ServiceMetadata serviceMetadata;
public DemoPrimitiveProcessor(Storage storage) {
this.storage = storage;
@ -62,7 +62,7 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
/*
@ -114,13 +114,12 @@ public class DemoPrimitiveProcessor implements PrimitiveProcessor {
Object value = property.getValue();
if (value != null) {
// 3.1. configure the serializer
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
// 3.2. serialize
SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
InputStream propertyStream = serializerResult.getContent();
// 4. configure the response object

View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.group.id</groupId>
<artifactId>DemoService-QueryOptions-O</artifactId>
<packaging>war</packaging>
<version>4.0.0</version>
<name>${project.artifactId}-Webapp</name>
<build>
<finalName>DemoService</finalName>
</build>
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${javax.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-server-api</artifactId>
<version>${odata.version}</version>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-server-core</artifactId>
<version>${odata.version}</version>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-commons-api</artifactId>
<version>${odata.version}</version>
</dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>odata-commons-core</artifactId>
<version>${odata.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,153 @@
/*
* 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.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
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.CsdlEntityContainer;
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.CsdlEntityType;
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.CsdlSchema;
public class DemoEdmProvider extends CsdlAbstractEdmProvider {
// Service Namespace
public static final String NAMESPACE = "OData.Demo";
// EDM Container
public static final String CONTAINER_NAME = "Container";
public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME);
// Entity Types Names
public static final String ET_PRODUCT_NAME = "Product";
public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME);
// Entity Set Names
public static final String ES_PRODUCTS_NAME = "Products";
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for one of the EntityTypes that are configured in the Schema
if(ET_PRODUCT_FQN.equals(entityTypeName)){
//create EntityType properties
CsdlProperty id = new CsdlProperty().setName("ID")
.setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
CsdlProperty name = new CsdlProperty().setName("Name")
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
CsdlProperty description = new CsdlProperty().setName("Description")
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
// create PropertyRef for Key element
CsdlPropertyRef propertyRef = new CsdlPropertyRef();
propertyRef.setName("ID");
// configure EntityType
CsdlEntityType entityType = new CsdlEntityType();
entityType.setName(ET_PRODUCT_NAME);
entityType.setProperties(Arrays.asList(id, name, description));
entityType.setKey(Collections.singletonList(propertyRef));
return entityType;
}
return null;
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
if(entityContainer.equals(CONTAINER)){
if(entitySetName.equals(ES_PRODUCTS_NAME)){
CsdlEntitySet entitySet = new CsdlEntitySet();
entitySet.setName(ES_PRODUCTS_NAME);
entitySet.setType(ET_PRODUCT_FQN);
return entitySet;
}
}
return null;
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document at
// e.g. http://localhost:8080/DemoService/DemoService.svc
if(entityContainerName == null || entityContainerName.equals(CONTAINER)){
CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
entityContainerInfo.setContainerName(CONTAINER);
return entityContainerInfo;
}
return null;
}
@Override
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
schema.setNamespace(NAMESPACE);
// add EntityTypes
List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
entityTypes.add(getEntityType(ET_PRODUCT_FQN));
schema.setEntityTypes(entityTypes);
// add EntityContainer
schema.setEntityContainer(getEntityContainer());
// finally
List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
schemas.add(schema);
return schemas;
}
@Override
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
// create EntityContainer
CsdlEntityContainer entityContainer = new CsdlEntityContainer();
entityContainer.setName(CONTAINER_NAME);
entityContainer.setEntitySets(entitySets);
return entityContainer;
}
}

View File

@ -0,0 +1,147 @@
/*
* 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.io.InputStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import myservice.mynamespace.data.Storage;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.api.uri.queryoption.expression.Member;
public class DemoEntityCollectionProcessor implements EntityCollectionProcessor {
private OData odata;
private ServiceMetadata serviceMetadata;
private Storage storage;
public DemoEntityCollectionProcessor(Storage storage) {
this.storage = storage;
}
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
public void readEntityCollection(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();
// in our example, the first segment is the EntitySet
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
// 2nd: fetch the data from backend for this requested EntitySetName and deliver as EntitySet
EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet);
List<Entity> entityList = entityCollection.getEntities();
// 3rd apply $orderby
OrderByOption orderByOption = uriInfo.getOrderByOption();
if (orderByOption != null) {
List<OrderByItem> orderItemList = orderByOption.getOrders();
final OrderByItem orderByItem = orderItemList.get(0); // in our example we support only one
Expression expression = orderByItem.getExpression();
if(expression instanceof Member){
UriInfoResource resourcePath = ((Member)expression).getResourcePath();
UriResource uriResource = resourcePath.getUriResourceParts().get(0);
if (uriResource instanceof UriResourcePrimitiveProperty) {
EdmProperty edmProperty = ((UriResourcePrimitiveProperty)uriResource).getProperty();
final String sortPropertyName = edmProperty.getName();
// do the sorting for the list of entities
Collections.sort(entityList, new Comparator<Entity>() {
// we delegate the sorting to the native sorter of Integer and String
public int compare(Entity entity1, Entity entity2) {
int compareResult = 0;
if(sortPropertyName.equals("ID")){
Integer integer1 = (Integer) entity1.getProperty(sortPropertyName).getValue();
Integer integer2 = (Integer) entity2.getProperty(sortPropertyName).getValue();
compareResult = integer1.compareTo(integer2);
}else{
String propertyValue1 = (String) entity1.getProperty(sortPropertyName).getValue();
String propertyValue2 = (String) entity2.getProperty(sortPropertyName).getValue();
compareResult = propertyValue1.compareTo(propertyValue2);
}
// if 'desc' is specified in the URI, change the order of the list
if(orderByItem.isDescending()){
return - compareResult; // just convert the result to negative value to change the order
}
return compareResult;
}
});
}
}
}
// 4th: create a serializer based on the requested format (json)
ODataSerializer serializer = odata.createSerializer(responseFormat);
// and serialize the content: transform from the EntitySet object to InputStream
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).build();
SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType,
entityCollection, opts);
InputStream serializedContent = serializerResult.getContent();
// 5th: configure the response object: set the body, headers and status code
response.setContent(serializedContent);
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
}

View File

@ -29,7 +29,6 @@ import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -88,8 +87,7 @@ public class DemoEntityProcessor implements EntityProcessor {
// expand and select currently not supported
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options);
InputStream entityStream = serializerResult.getContent();
@ -105,22 +103,20 @@ public class DemoEntityProcessor implements EntityProcessor {
/*
* These processor methods are not handled in this tutorial
* */
public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat)
throws ODataApplicationException, DeserializerException, SerializerException {
public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat)
throws ODataApplicationException, DeserializerException, SerializerException {
public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException {
public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
throws ODataApplicationException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}

View File

@ -0,0 +1,148 @@
/*
* 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.io.InputStream;
import java.util.List;
import java.util.Locale;
import myservice.mynamespace.data.Storage;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceProperty;
public class DemoPrimitiveProcessor implements PrimitiveProcessor {
private OData odata;
private Storage storage;
private ServiceMetadata serviceMetadata;
public DemoPrimitiveProcessor(Storage storage) {
this.storage = storage;
}
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
/*
* In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name
* and the response:
* {
* @odata.context: "$metadata#Products/Name",
* value: "Notebook Basic 15"
* }
* */
public void readPrimitive(ODataRequest request, ODataResponse response,UriInfo uriInfo, ContentType responseFormat)
throws ODataApplicationException, SerializerException {
// 1. Retrieve info from URI
// 1.1. retrieve the info about the requested entity set
List<UriResource> resourceParts = uriInfo.getUriResourceParts();
// Note: only in our example we can rely that the first segment is the EntitySet
UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0);
EdmEntitySet edmEntitySet = uriEntityset.getEntitySet();
// the key for the entity
List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();
// 1.2. retrieve the requested (Edm) property
// the last segment is the Property
UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1);
EdmProperty edmProperty = uriProperty.getProperty();
String edmPropertyName = edmProperty.getName();
// in our example, we know we have only primitive types in our model
EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType();
// 2. retrieve data from backend
// 2.1. retrieve the entity data, for which the property has to be read
Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
if (entity == null) { // Bad request
throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
}
// 2.2. retrieve the property data from the entity
Property property = entity.getProperty(edmPropertyName);
if (property == null) {
throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(),
Locale.ENGLISH);
}
// 3. serialize
Object value = property.getValue();
if (value != null) {
// 3.1. configure the serializer
ODataSerializer serializer = odata.createSerializer(responseFormat);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
// 3.2. serialize
SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
InputStream propertyStream = serializerResult.getContent();
//4. configure the response object
response.setContent(propertyStream);
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
} else {
// in case there's no value for the property, we can skip the serialization
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
}
}
/*
* These processor methods are not handled in this tutorial
* */
public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo)
throws ODataApplicationException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}

View File

@ -0,0 +1,101 @@
/*
* 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.util;
import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriParameter;
public class Util {
public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
List<UriParameter> keyParams) throws ODataApplicationException {
List<Entity> entityList = entitySet.getEntities();
// loop over all entities in order to find that one that matches all keys in request
// e.g. contacts(ContactID=1, CompanyID=1)
for (Entity entity: entityList) {
boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams);
if (foundEntity) {
return entity;
}
}
return null;
}
public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List<UriParameter> keyParams)
throws ODataApplicationException {
// loop over all keys
for (final UriParameter key : keyParams) {
// key
String keyName = key.getName();
String keyText = key.getText();
// Edm: we need this info for the comparison below
EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(keyName);
Boolean isNullable = edmKeyProperty.isNullable();
Integer maxLength = edmKeyProperty.getMaxLength();
Integer precision = edmKeyProperty.getPrecision();
Boolean isUnicode = edmKeyProperty.isUnicode();
Integer scale = edmKeyProperty.getScale();
// get the EdmType in order to compare
EdmType edmType = edmKeyProperty.getType();
EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType;
// Runtime data: the value of the current entity
// don't need to check for null, this is done in olingo library
Object valueObject = entity.getProperty(keyName).getValue();
// now need to compare the valueObject with the keyText String
// this is done using the type.valueToString
String valueAsString;
try {
valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable, maxLength, precision, scale, isUnicode);
} catch (EdmPrimitiveTypeException e) {
throw new ODataApplicationException("Failed to retrieve String value", HttpStatusCode.INTERNAL_SERVER_ERROR
.getStatusCode(), Locale.ENGLISH, e);
}
if (valueAsString == null) {
return false;
}
boolean matches = valueAsString.equals(keyText);
if (!matches) {
// if any of the key properties is not found in the entity, we don't need to search further
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.web;
import java.io.IOException;
import java.lang.Override;import java.lang.RuntimeException;import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import myservice.mynamespace.data.Storage;
import myservice.mynamespace.service.DemoEdmProvider;
import myservice.mynamespace.service.DemoEntityCollectionProcessor;
import myservice.mynamespace.service.DemoEntityProcessor;
import myservice.mynamespace.service.DemoPrimitiveProcessor;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class);
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
HttpSession session = req.getSession(true);
Storage storage = (Storage) session.getAttribute(Storage.class.getName());
if (storage == null) {
storage = new Storage();
session.setAttribute(Storage.class.getName(), storage);
}
// create odata handler and configure it with EdmProvider and Processor
OData odata = OData.newInstance();
ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList<EdmxReference>());
ODataHttpHandler handler = odata.createHandler(edm);
handler.register(new DemoEntityCollectionProcessor(storage));
handler.register(new DemoEntityProcessor(storage));
handler.register(new DemoPrimitiveProcessor(storage));
// let the handler do the work
handler.process(req, resp);
} catch (RuntimeException e) {
LOG.error("Server Error occurred in ExampleServlet", e);
throw new ServletException(e);
}
}
}

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- Register the HttpServlet implementation -->
<servlet>
<servlet-name>DemoServlet</servlet-name>
<servlet-class>myservice.mynamespace.web.DemoServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--
Our OData service can be invoked at
http://localhost:8080/DemoService/DemoService.svc
-->
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name>
<url-pattern>/DemoService.svc/*</url-pattern>
</servlet-mapping>
</web-app>

View File

@ -0,0 +1,26 @@
<!--
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.
-->
<html>
<body>
<h2>Hello World!</h2>
<a href="DemoService.svc/">OData Olingo V4 Demo Service</a>
</body>
</html>

View File

@ -25,7 +25,7 @@
<groupId>my.group.id</groupId>
<artifactId>DemoService-QueryOptions-F</artifactId>
<packaging>war</packaging>
<version>0.0.1</version>
<version>4.0.0</version>
<name>${project.artifactId} Webapp</name>
@ -35,7 +35,7 @@
<properties>
<javax.version>2.5</javax.version>
<odata.version>4.0.0-beta-03</odata.version>
<odata.version>4.0.0-SNAPSHOT</odata.version>
<slf4j.version>1.7.7</slf4j.version>
</properties>
@ -76,5 +76,11 @@
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,125 @@
/*
* 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.data;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import myservice.mynamespace.service.DemoEdmProvider;
import myservice.mynamespace.util.Util;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriParameter;
public class Storage {
private List<Entity> productList;
public Storage() {
productList = new ArrayList<Entity>();
initSampleData();
}
/* PUBLIC FACADE */
public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet)throws ODataApplicationException{
// actually, this is only required if we have more than one Entity Sets
if(edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)){
return getProducts();
}
return null;
}
public Entity readEntityData(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)){
return getProduct(edmEntityType, keyParams);
}
return null;
}
/* INTERNAL */
private EntityCollection getProducts(){
EntityCollection retEntitySet = new EntityCollection();
for(Entity productEntity : this.productList){
retEntitySet.getEntities().add(productEntity);
}
return retEntitySet;
}
private Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams) throws ODataApplicationException{
// the list of entities at runtime
EntityCollection entitySet = getProducts();
/* generic approach to find the requested entity */
Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams);
if(requestedEntity == null){
// this variable is null if our data doesn't contain an entity for the requested key
// Throw suitable exception
throw new ODataApplicationException("Entity for requested key doesn't exist",
HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
}
return requestedEntity;
}
/* HELPER */
private void initSampleData(){
// add some sample product entities
productList.add(new Entity()
.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1))
.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"))
.addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB")));
productList.add(new Entity()
.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2))
.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"))
.addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network")));
productList.add(new Entity()
.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3))
.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"))
.addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960")));
}
}

View File

@ -23,7 +23,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
@ -53,15 +52,16 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName)
throws ODataException {
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
// this method is called for one of the EntityTypes that are configured in the Schema
if(ET_PRODUCT_FQN.equals(entityTypeName)){
//create EntityType properties
CsdlProperty id = new CsdlProperty().setName("ID").setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
CsdlProperty name = new CsdlProperty().setName("Name").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
CsdlProperty description = new CsdlProperty().setName("Description").setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
CsdlProperty name = new CsdlProperty().setName("Name")
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
CsdlProperty description = new CsdlProperty().setName("Description")
.setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
// create PropertyRef for Key element
CsdlPropertyRef propertyRef = new CsdlPropertyRef();
@ -77,12 +77,10 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
return null;
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer,
String entitySetName) throws ODataException {
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
if(entityContainer.equals(CONTAINER)){
if(entitySetName.equals(ES_PRODUCTS_NAME)){
CsdlEntitySet entitySet = new CsdlEntitySet();
@ -94,13 +92,12 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
return null;
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(
FullQualifiedName entityContainerName) throws ODataException {
// This method is invoked when displaying the service document at e.g. http://localhost:8080/DemoService/DemoService.svc
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) {
// This method is invoked when displaying the service document at
// e.g. http://localhost:8080/DemoService/DemoService.svc
if(entityContainerName == null || entityContainerName.equals(CONTAINER)){
CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
entityContainerInfo.setContainerName(CONTAINER);
@ -108,11 +105,10 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
return null;
}
@Override
public List<CsdlSchema> getSchemas() throws ODataException {
public List<CsdlSchema> getSchemas() {
// create Schema
CsdlSchema schema = new CsdlSchema();
schema.setNamespace(NAMESPACE);
@ -134,7 +130,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
}
@Override
public CsdlEntityContainer getEntityContainer() throws ODataException {
public CsdlEntityContainer getEntityContainer() {
// create EntitySets
List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
@ -145,9 +141,5 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
entityContainer.setEntitySets(entitySets);
return entityContainer;
}
}

View File

@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
@ -66,11 +65,13 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
this.serviceMetadata = serviceMetadata;
}
public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, SerializerException {
public void readEntityCollection(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();
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet
// in our example, the first segment is the EntitySet
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
// 2nd: fetch the data from backend for this requested EntitySetName and deliver as EntitySet
@ -98,8 +99,8 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
// The result of the filter expression must be of type Edm.Boolean
if(visitorResult instanceof Boolean) {
if(visitorResult != null && Boolean.FALSE.equals(visitorResult)) {
// The expression evaluated to false, so we have to remove the currentEntity from entityList
if(!Boolean.TRUE.equals(visitorResult)) {
// The expression evaluated to false (or null), so we have to remove the currentEntity from entityList
entityIterator.remove();
}
} else {
@ -115,15 +116,15 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
}
// 4th: create a serializer based on the requested format (json)
ODataFormat format = ODataFormat.fromContentType(responseFormat);
ODataSerializer serializer = odata.createSerializer(format);
ODataSerializer serializer = odata.createSerializer(responseFormat);
// and serialize the content: transform from the EntitySet object to InputStream
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).build();
SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entityCollection, opts);
SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType,
entityCollection, opts);
InputStream serializedContent = serializerResult.getContent();
// 5th: configure the response object: set the body, headers and status code

View File

@ -0,0 +1,122 @@
/*
* 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.io.InputStream;
import java.util.List;
import java.util.Locale;
import myservice.mynamespace.data.Storage;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.processor.EntityProcessor;
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
public class DemoEntityProcessor implements EntityProcessor {
private OData odata;
private ServiceMetadata serviceMetadata;
private Storage storage;
public DemoEntityProcessor(Storage storage) {
this.storage = storage;
}
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
throws ODataApplicationException, SerializerException {
// 1. retrieve the Entity Type
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
// Note: only in our example we can assume that the first segment is the EntitySet
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
// 2. retrieve the data from backend
List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
// 3. serialize
EdmEntityType entityType = edmEntitySet.getEntityType();
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).suffix(ContextURL.Suffix.ENTITY).build();
// expand and select currently not supported
EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
ODataSerializer serializer = this.odata.createSerializer(responseFormat);
SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options);
InputStream entityStream = serializerResult.getContent();
//4. configure the response object
response.setContent(entityStream);
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
/*
* These processor methods are not handled in this tutorial
* */
public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
throws ODataApplicationException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}

View File

@ -0,0 +1,150 @@
/*
* 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.io.InputStream;
import java.util.List;
import java.util.Locale;
import myservice.mynamespace.data.Storage;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceProperty;
public class DemoPrimitiveProcessor implements PrimitiveProcessor {
private OData odata;
private Storage storage;
private ServiceMetadata serviceMetadata;
public DemoPrimitiveProcessor(Storage storage) {
this.storage = storage;
}
public void init(OData odata, ServiceMetadata serviceMetadata) {
this.odata = odata;
this.serviceMetadata = serviceMetadata;
}
/*
* In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name
* and the response:
* {
* @odata.context: "$metadata#Products/Name",
* value: "Notebook Basic 15"
* }
* */
public void readPrimitive(ODataRequest request, ODataResponse response,
UriInfo uriInfo, ContentType responseFormat)
throws ODataApplicationException, SerializerException {
// 1. Retrieve info from URI
// 1.1. retrieve the info about the requested entity set
List<UriResource> resourceParts = uriInfo.getUriResourceParts();
// Note: only in our example we can rely that the first segment is the EntitySet
UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0);
EdmEntitySet edmEntitySet = uriEntityset.getEntitySet();
// the key for the entity
List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();
// 1.2. retrieve the requested (Edm) property
// the last segment is the Property
UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1);
EdmProperty edmProperty = uriProperty.getProperty();
String edmPropertyName = edmProperty.getName();
// in our example, we know we have only primitive types in our model
EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType();
// 2. retrieve data from backend
// 2.1. retrieve the entity data, for which the property has to be read
Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
if (entity == null) { // Bad request
throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
}
// 2.2. retrieve the property data from the entity
Property property = entity.getProperty(edmPropertyName);
if (property == null) {
throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(),
Locale.ENGLISH);
}
// 3. serialize
Object value = property.getValue();
if (value != null) {
// 3.1. configure the serializer
ODataSerializer serializer = odata.createSerializer(responseFormat);
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
// 3.2. serialize
SerializerResult serializerResult = serializer.primitive(serviceMetadata, edmPropertyType, property, options);
InputStream propertyStream = serializerResult.getContent();
//4. configure the response object
response.setContent(propertyStream);
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
} else {
// in case there's no value for the property, we can skip the serialization
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
}
}
/*
* These processor methods are not handled in this tutorial
* */
public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
ContentType responseFormat) throws ODataApplicationException, DeserializerException, SerializerException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo)
throws ODataApplicationException {
throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}

View File

@ -0,0 +1,303 @@
/*
* 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.List;
import java.util.Locale;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
public class FilterExpressionVisitor implements ExpressionVisitor<Object> {
private Entity currentEntity;
public FilterExpressionVisitor(Entity currentEntity) {
this.currentEntity = currentEntity;
}
@Override
public Object visitMember(UriInfoResource member) throws ExpressionVisitException, ODataApplicationException {
// To keeps things simple, this tutorial allows only primitive properties.
// We have faith that the java type of Edm.Int32 is Integer
final List<UriResource> uriResourceParts = member.getUriResourceParts();
// Make sure that the resource path of the property contains only a single segment and a primitive property
// has been addressed. We can be sure, that the property exists because the UriParser checks if the
// property has been defined in service metadata document.
if(uriResourceParts.size() == 1 && uriResourceParts.get(0) instanceof UriResourcePrimitiveProperty) {
UriResourcePrimitiveProperty uriResourceProperty = (UriResourcePrimitiveProperty) uriResourceParts.get(0);
return currentEntity.getProperty(uriResourceProperty.getProperty().getName()).getValue();
} else {
// The OData specification allows in addition complex properties and navigation properties
// with a target cardinality 0..1 or 1.
// This means any combination can occur e.g. Supplier/Address/City
// -> Navigation properties Supplier
// -> Complex Property Address
// -> Primitive Property City
// For such cases the resource path returns a list of UriResourceParts
throw new ODataApplicationException("Only primitive properties are implemented in filter expressions",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}
@Override
public Object visitLiteral(Literal literal) throws ExpressionVisitException, ODataApplicationException {
// To keep this tutorial simple, our filter expression visitor supports only Edm.Int32 and Edm.String
// In real world scenarios it can be difficult to guess the type of an literal.
// We can be sure, that the literal is a valid OData literal because the URI Parser checks
// the lexicographical structure
// String literals start and end with an single quotation mark
String literalAsString = literal.getText();
if(literal.getType() instanceof EdmString) {
String stringLiteral = "";
if(literal.getText().length() > 2) {
stringLiteral = literalAsString.substring(1, literalAsString.length() - 1);
}
return stringLiteral;
} else {
// Try to convert the literal into an Java Integer
try {
return Integer.parseInt(literalAsString);
} catch(NumberFormatException e) {
throw new ODataApplicationException("Only Edm.Int32 and Edm.String literals are implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}
}
@Override
public Object visitUnaryOperator(UnaryOperatorKind operator, Object operand)
throws ExpressionVisitException, ODataApplicationException {
// OData allows two different unary operators. We have to take care, that the type of the operand fits to
// operand
if(operator == UnaryOperatorKind.NOT && operand instanceof Boolean) {
// 1.) boolean negation
return !(Boolean) operand;
} else if(operator == UnaryOperatorKind.MINUS && operand instanceof Integer){
// 2.) arithmetic minus
return -(Integer) operand;
}
// Operation not processed, throw an exception
throw new ODataApplicationException("Invalid type for unary operator",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
@Override
public Object visitBinaryOperator(BinaryOperatorKind operator, Object left, Object right)
throws ExpressionVisitException, ODataApplicationException {
// Binary Operators are split up in three different kinds. Up to the kind of the operator it can be applied
// to different types
// - Arithmetic operations like add, minus, modulo, etc. are allowed on numeric types like Edm.Int32
// - Logical operations are allowed on numeric types and also Edm.String
// - Boolean operations like and, or are allowed on Edm.Boolean
// A detailed explanation can be found in OData Version 4.0 Part 2: URL Conventions
if (operator == BinaryOperatorKind.ADD
|| operator == BinaryOperatorKind.MOD
|| operator == BinaryOperatorKind.MUL
|| operator == BinaryOperatorKind.DIV
|| operator == BinaryOperatorKind.SUB) {
return evaluateArithmeticOperation(operator, left, right);
} else if (operator == BinaryOperatorKind.EQ
|| operator == BinaryOperatorKind.NE
|| operator == BinaryOperatorKind.GE
|| operator == BinaryOperatorKind.GT
|| operator == BinaryOperatorKind.LE
|| operator == BinaryOperatorKind.LT) {
return evaluateComparisonOperation(operator, left, right);
} else if (operator == BinaryOperatorKind.AND
|| operator == BinaryOperatorKind.OR) {
return evaluateBooleanOperation(operator, left, right);
} else {
throw new ODataApplicationException("Binary operation " + operator.name() + " is not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}
private Object evaluateBooleanOperation(BinaryOperatorKind operator, Object left, Object right)
throws ODataApplicationException {
// First check that both operands are of type Boolean
if(left instanceof Boolean && right instanceof Boolean) {
Boolean valueLeft = (Boolean) left;
Boolean valueRight = (Boolean) right;
// Than calculate the result value
if(operator == BinaryOperatorKind.AND) {
return valueLeft && valueRight;
} else {
// OR
return valueLeft || valueRight;
}
} else {
throw new ODataApplicationException("Boolean operations needs two numeric operands",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
}
private Object evaluateComparisonOperation(BinaryOperatorKind operator, Object left, Object right)
throws ODataApplicationException {
// All types in our tutorial supports all logical operations, but we have to make sure that the types are equals
if(left.getClass().equals(right.getClass()) && left instanceof Comparable) {
// Luckily all used types String, Boolean and also Integer support the interface Comparable
int result;
if(left instanceof Integer) {
result = ((Comparable<Integer>) (Integer)left).compareTo((Integer) right);
} else if(left instanceof String) {
result = ((Comparable<String>) (String)left).compareTo((String) right);
} else if(left instanceof Boolean) {
result = ((Comparable<Boolean>) (Boolean)left).compareTo((Boolean) right);
} else {
throw new ODataApplicationException("Class " + left.getClass().getCanonicalName() + " not expected",
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ENGLISH);
}
if (operator == BinaryOperatorKind.EQ) {
return result == 0;
} else if (operator == BinaryOperatorKind.NE) {
return result != 0;
} else if (operator == BinaryOperatorKind.GE) {
return result >= 0;
} else if (operator == BinaryOperatorKind.GT) {
return result > 0;
} else if (operator == BinaryOperatorKind.LE) {
return result <= 0;
} else {
// BinaryOperatorKind.LT
return result < 0;
}
} else {
throw new ODataApplicationException("Comparision needs two equal types",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
}
private Object evaluateArithmeticOperation(BinaryOperatorKind operator, Object left,
Object right) throws ODataApplicationException {
// First check if the type of both operands is numerical
if(left instanceof Integer && right instanceof Integer) {
Integer valueLeft = (Integer) left;
Integer valueRight = (Integer) right;
// Than calculate the result value
if(operator == BinaryOperatorKind.ADD) {
return valueLeft + valueRight;
} else if(operator == BinaryOperatorKind.SUB) {
return valueLeft - valueRight;
} else if(operator == BinaryOperatorKind.MUL) {
return valueLeft * valueRight;
} else if(operator == BinaryOperatorKind.DIV) {
return valueLeft / valueRight;
} else {
// BinaryOperatorKind,MOD
return valueLeft % valueRight;
}
} else {
throw new ODataApplicationException("Arithmetic operations needs two numeric operands",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
}
@Override
public Object visitMethodCall(MethodKind methodCall, List<Object> parameters)
throws ExpressionVisitException, ODataApplicationException {
// To keep this tutorial small and simple, we implement only one method call
if(methodCall == MethodKind.CONTAINS) {
// "Contains" gets two parameters, both have to be of type String
// e.g. /Products?$filter=contains(Description, '1024 MB')
//
// First the method visistMember is called, which returns the current String value of the property.
// After that the method visitLiteral is called with the string literal '1024 MB',
// which returns a String
//
// Both String values are passed to visitMethodCall.
if(parameters.get(0) instanceof String && parameters.get(1) instanceof String) {
String valueParam1 = (String) parameters.get(0);
String valueParam2 = (String) parameters.get(1);
return valueParam1.contains(valueParam2);
} else {
throw new ODataApplicationException("Contains needs two parametes of type Edm.String",
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ENGLISH);
}
} else {
throw new ODataApplicationException("Method call " + methodCall + " not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}
@Override
public Object visitTypeLiteral(EdmType type) throws ExpressionVisitException, ODataApplicationException {
throw new ODataApplicationException("Type literals are not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
@Override
public Object visitAlias(String aliasName) throws ExpressionVisitException, ODataApplicationException {
throw new ODataApplicationException("Aliases are not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
@Override
public Object visitEnum(EdmEnumType type, List<String> enumValues)
throws ExpressionVisitException, ODataApplicationException {
throw new ODataApplicationException("Enums are not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
@Override
public Object visitLambdaExpression(String lambdaFunction, String lambdaVariable, Expression expression)
throws ExpressionVisitException, ODataApplicationException {
throw new ODataApplicationException("Lamdba expressions are not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
@Override
public Object visitLambdaReference(String variableName)
throws ExpressionVisitException, ODataApplicationException {
throw new ODataApplicationException("Lamdba references are not implemented",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.web;
import java.io.IOException;
import java.lang.Override;import java.lang.RuntimeException;import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import myservice.mynamespace.data.Storage;
import myservice.mynamespace.service.DemoEdmProvider;
import myservice.mynamespace.service.DemoEntityCollectionProcessor;
import myservice.mynamespace.service.DemoEntityProcessor;
import myservice.mynamespace.service.DemoPrimitiveProcessor;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class);
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
HttpSession session = req.getSession(true);
Storage storage = (Storage) session.getAttribute(Storage.class.getName());
if (storage == null) {
storage = new Storage();
session.setAttribute(Storage.class.getName(), storage);
}
// create odata handler and configure it with EdmProvider and Processor
OData odata = OData.newInstance();
ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList<EdmxReference>());
ODataHttpHandler handler = odata.createHandler(edm);
handler.register(new DemoEntityCollectionProcessor(storage));
handler.register(new DemoEntityProcessor(storage));
handler.register(new DemoPrimitiveProcessor(storage));
// let the handler do the work
handler.process(req, resp);
} catch (RuntimeException e) {
LOG.error("Server Error occurred in ExampleServlet", e);
throw new ServletException(e);
}
}
}

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- Register the HttpServlet implementation -->
<servlet>
<servlet-name>DemoServlet</servlet-name>
<servlet-class>myservice.mynamespace.web.DemoServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--
Our OData service can be invoked at
http://localhost:8080/DemoService/DemoService.svc
-->
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name>
<url-pattern>/DemoService.svc/*</url-pattern>
</servlet-mapping>
</web-app>

View File

@ -0,0 +1,24 @@
/*
* 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.
*/
<html>
<body>
<h2>Hello World!</h2>
<a href="DemoService.svc/">OData Olingo V4 Demo Service</a>
</body>
</html>

View File

@ -35,13 +35,15 @@
</parent>
<modules>
<module>p0_all</module>
<module>p1_read</module>
<module>p2_readep</module>
<module>p3_write</module>
<module>p4_navigation</module>
<module>p5_queryoptions-tcs</module>
<module>p6_queryoptions-es</module>
<module>p7_queryoptions-f</module>
<module>p7_queryoptions-o</module>
<module>p8_queryoptions-f</module>
</modules>
<build>