resourcePaths = uriInfo.getUriResourceParts();
+ UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet
+ EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+ // 2nd: fetch the data from backend for this requested EntitySetName
+ Long count = getCount(edmEntitySet, uriInfo);
+
+ // Finally: configure the response object: set the body, headers and status code
+ response.setContent(new ByteArrayInputStream(count.toString().getBytes()));
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain");
+
+ }
+
+ /**
+ * Helper method to retrieve all entities of an entity set from an the backend database
+ * @param edmEntitySet
+ * @param uriInfo
+ * @return
+ */
+ protected EntityCollection getData(EdmEntitySet edmEntitySet, UriInfo uriInfo) {
+
+ EdmEntityType type = edmEntitySet.getEntityType();
+ JpaRepository, ?> repo = (JpaRepository, ?>)repositoryRegistry.getRepositoryForEntity(type);
+ EntityCollection result = new EntityCollection();
+
+ repo.findAll()
+ .stream()
+ .forEach((it) -> result.getEntities()
+ .add(entityMapper.map2entity(edmEntitySet, it)));
+
+ return result;
+ }
+
+
+ /**
+ * Helper method to get the total size of an entity set
+ * @param edmEntitySet
+ * @param uriInfo
+ * @return
+ */
+ protected Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) {
+
+ EdmEntityType type = edmEntitySet.getEntityType();
+ JpaRepository, ?> repo = (JpaRepository, ?>)repositoryRegistry.getRepositoryForEntity(type);
+ EntityCollection result = new EntityCollection();
+
+ return repo.count();
+ }
+
+
+
+
+}
diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java
new file mode 100644
index 0000000000..1978aa4fd6
--- /dev/null
+++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java
@@ -0,0 +1,93 @@
+/**
+ *
+ */
+package org.baeldung.examples.olingo4.processor;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.metamodel.EntityType;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.olingo.commons.api.data.Entity;
+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.ex.ODataRuntimeException;
+import org.springframework.stereotype.Component;
+
+/**
+ * Helper class that converts a JPA entity into an OData entity using
+ * available metadata from the JPA's EntityManagerFactory.
+ *
+ * @author Philippe
+ *
+ */
+@Component
+public class JpaEntityMapper {
+
+ private EntityManagerFactory emf;
+
+ public JpaEntityMapper(EntityManagerFactory emf) {
+ this.emf = emf;
+ }
+
+
+ public Entity map2entity(EdmEntitySet edmEntitySet, Object entry) {
+
+ EntityType> et = emf.getMetamodel()
+ .entity(entry.getClass());
+
+
+ Entity e = new Entity();
+ try {
+ et.getDeclaredSingularAttributes().stream()
+ .forEach( (attr) -> {
+ if ( !attr.isAssociation()) {
+ Object v = getPropertyValue(entry,attr.getName());
+ Property p = new Property(null, attr.getName(),ValueType.PRIMITIVE,v);
+ e.addProperty(p);
+
+ if ( attr.isId()) {
+ e.setId(createId(edmEntitySet.getName(),v));
+ }
+ }
+ });
+ } catch (Exception ex) {
+ throw new ODataRuntimeException("[E141] Unable to create OData entity", ex);
+ }
+
+ return e;
+ }
+
+
+ public Object getPropertyValue(Object entry, String name) {
+ try {
+ return PropertyUtils.getProperty(entry,name);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e);
+ }
+ }
+
+ public void setPropertyValue(Object entry, String name,Object value) {
+ try {
+ PropertyUtils.setProperty(entry,name,value);
+ } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+ throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e);
+ }
+ }
+
+
+ private URI createId(String entitySetName, Object id) {
+ try {
+ return new URI(entitySetName + "(" + String.valueOf(id) + ")");
+ } catch (URISyntaxException e) {
+ throw new ODataRuntimeException("[E177] Unable to create URI", e);
+ }
+ }
+
+
+
+}
diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java
new file mode 100644
index 0000000000..719e5de160
--- /dev/null
+++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java
@@ -0,0 +1,304 @@
+/**
+ *
+ */
+package org.baeldung.examples.olingo4.processor;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Locale;
+import java.util.Optional;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.metamodel.SingularAttribute;
+
+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.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.ex.ODataRuntimeException;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+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.baeldung.examples.olingo4.repository.EdmEntityRepository;
+import org.baeldung.examples.olingo4.repository.RepositoryRegistry;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Component;
+
+/**
+ * JpaEntityProcessor adapter.
+ * This implementation is heavily based on the Tutorial available
+ * at Olingo's site. It is meant to be an starting point for an actual implementation.
+ * Please note that many features from a full-fledged are missing
+ * @author Philippe
+ *
+ */
+@Component
+public class JpaEntityProcessor implements EntityProcessor {
+
+ private EntityManagerFactory emf;
+ private OData odata;
+ private ServiceMetadata serviceMetadata;
+ private RepositoryRegistry registry;
+ private JpaEntityMapper entityMapper;
+
+ public JpaEntityProcessor(EntityManagerFactory emf, RepositoryRegistry registry, JpaEntityMapper entityMapper) {
+ this.emf = emf;
+ this.registry = registry;
+ this.entityMapper = entityMapper;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.olingo.server.api.processor.Processor#init(org.apache.olingo.server.api.OData, org.apache.olingo.server.api.ServiceMetadata)
+ */
+ @Override
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+ this.serviceMetadata = serviceMetadata;
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.olingo.server.api.processor.EntityProcessor#readEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType)
+ */
+ @Override
+ public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
+
+ // First, we have to figure out which entity is requested
+ List resourceParts = uriInfo.getUriResourceParts();
+ InputStream entityStream;
+
+ UriResourceEntitySet rootResourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
+ EdmEntitySet rootEntitySet = rootResourceEntitySet.getEntitySet();
+ List rootPredicates = rootResourceEntitySet.getKeyPredicates();
+
+ if ( resourceParts.size() == 1 ) {
+ entityStream = readRootEntity(rootEntitySet,rootPredicates,responseFormat);
+ }
+ else if ( resourceParts.size() == 2 ) {
+ UriResource part = resourceParts.get(1);
+ if ( !(part instanceof UriResourceNavigation)) {
+ throw new ODataRuntimeException("[E103] part type not supported: class=" + part.getClass().getName());
+ }
+
+ UriResourceNavigation navSegment = (UriResourceNavigation)part;
+ entityStream = readRelatedEntity(request, rootEntitySet,rootPredicates,navSegment.getProperty(),navSegment.getKeyPredicates(),responseFormat);
+ }
+ else {
+ // For now, we'll only allow navigation just to directly linked navs
+ throw new ODataApplicationException("[E109] Multi-level navigation not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ //4. configure the response object
+ response.setContent(entityStream);
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+
+ }
+
+
+ // Lookup the EntitySet associated with an EntityType
+ // In our example, we assume we have only one entityset for each entity type
+ private EdmEntitySet entitySetFromType(EdmEntityType type) {
+ return serviceMetadata
+ .getEdm()
+ .getEntityContainer()
+ .getEntitySets()
+ .stream()
+ .filter((s) -> s.getEntityType().getName().equals(type.getName()))
+ .findFirst()
+ .orElseThrow(() -> new ODataRuntimeException("[E144] No entity set found for type " + type.getFullQualifiedName()));
+ }
+
+ //
+ // private boolean isOne2ManyProperty(EdmEntityType entityType, EdmNavigationProperty property) {
+ // return entityType.getProperty(property.getName()) != null && property.isCollection();
+ //}
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private InputStream readRootEntity(EdmEntitySet entitySet, List keyPredicates,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
+ EdmEntityType type = entitySet.getEntityType();
+ JpaRepository repo = registry.getRepositoryForEntity(type);
+
+ // Get key value
+ Long keyValue = getEntityKey(keyPredicates);
+ Optional