You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2014/11/07 14:50:18 UTC

[2/3] olingo-odata4 git commit: [OLINGO-482] split server processor interfaces + improved dispatching

[OLINGO-482] split server processor interfaces + improved dispatching

Change-Id: Ie57a469299e73662838307f1b96b558d3beb723d

Signed-off-by: Christian Amend <ch...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/a405e5b4
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/a405e5b4
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/a405e5b4

Branch: refs/heads/master
Commit: a405e5b4b5acfa484357c1b1df0b1dac9eb34a77
Parents: 3e11738
Author: Klaus Straubinger <kl...@sap.com>
Authored: Thu Nov 6 13:19:20 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Fri Nov 7 14:48:26 2014 +0100

----------------------------------------------------------------------
 .../ComplexTypeCollectionProcessor.java         |  46 +++
 .../api/processor/ComplexTypeProcessor.java     |  45 +++
 .../CountEntityTypeCollectionProcessor.java     |  44 +++
 .../server/api/processor/EntityProcessor.java   |  44 ---
 .../api/processor/EntitySetProcessor.java       |  58 ---
 .../EntityTypeCollectionProcessor.java          |  45 +++
 .../api/processor/EntityTypeProcessor.java      |  44 +++
 .../PrimitiveTypeCollectionProcessor.java       |  46 +++
 .../api/processor/PrimitiveTypeProcessor.java   |  60 +++
 .../server/api/processor/PropertyProcessor.java |  62 ---
 .../apache/olingo/server/core/ODataHandler.java | 164 ++++----
 .../olingo/server/tecsvc/TechnicalServlet.java  |   6 +-
 .../processor/TechnicalEntityProcessor.java     | 163 ++++++++
 .../TechnicalPrimitiveComplexProcessor.java     | 224 +++++++++++
 .../tecsvc/processor/TechnicalProcessor.java    | 283 +------------
 .../core/ODataHandlerExceptionHandlingTest.java | 210 ----------
 .../olingo/server/core/ODataHandlerTest.java    | 396 +++++++++----------
 17 files changed, 1022 insertions(+), 918 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ComplexTypeCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ComplexTypeCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ComplexTypeCollectionProcessor.java
new file mode 100644
index 0000000..42f676b
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ComplexTypeCollectionProcessor.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.apache.olingo.server.api.processor;
+
+import org.apache.olingo.commons.api.format.ContentType;
+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.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * Processor interface for handling a collection of complex-type instances, e.g.,
+ * a property of an entity defined as collection of complex-type instances.
+ */
+public interface ComplexTypeCollectionProcessor extends Processor {
+
+  /**
+   * Reads complex-type collection.
+   * If it is not available, for example due to permissions, the service responds with 404 Not Found.
+   * @param request  OData request object containing raw HTTP information
+   * @param response OData response object for collecting response data
+   * @param uriInfo  information of a parsed OData URI
+   * @param format   requested content type after content negotiation
+   * @throws ODataApplicationException if the service implementation encounters a failure
+   * @throws SerializerException       if serialization failed
+   */
+  void readComplexTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+      throws ODataApplicationException, SerializerException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ComplexTypeProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ComplexTypeProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ComplexTypeProcessor.java
new file mode 100644
index 0000000..05f9c3d
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ComplexTypeProcessor.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.apache.olingo.server.api.processor;
+
+import org.apache.olingo.commons.api.format.ContentType;
+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.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * Processor interface for handling a complex type, e.g., a complex property of an entity.
+ */
+public interface ComplexTypeProcessor extends Processor {
+
+  /**
+   * Reads complex type.
+   * If it is not available, for example due to permissions, the service responds with 404 Not Found.
+   * @param request  OData request object containing raw HTTP information
+   * @param response OData response object for collecting response data
+   * @param uriInfo  information of a parsed OData URI
+   * @param format   requested content type after content negotiation
+   * @throws ODataApplicationException if the service implementation encounters a failure
+   * @throws SerializerException       if serialization failed
+   */
+  void readComplexType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+      throws ODataApplicationException, SerializerException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityTypeCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityTypeCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityTypeCollectionProcessor.java
new file mode 100644
index 0000000..ecff637
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/CountEntityTypeCollectionProcessor.java
@@ -0,0 +1,44 @@
+/*
+ * 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 org.apache.olingo.server.api.processor;
+
+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.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * Processor interface for handling counting a collection of entities, e.g., an Entity Set.
+ */
+public interface CountEntityTypeCollectionProcessor extends Processor {
+
+  /**
+   * Counts entities from persistence and puts serialized content and status into the response.
+   * Response content type is <code>text/plain</code> by default.
+   * 
+   * @param request - OData request object containing raw http information.
+   * @param response - OData response object for collecting response data
+   * @param uriInfo - information of a parsed OData uri
+   * @throws ODataApplicationException
+   * @throws SerializerException
+   */
+  void countEntityTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo)
+      throws ODataApplicationException, SerializerException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityProcessor.java
deleted file mode 100644
index 783b3d2..0000000
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityProcessor.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 org.apache.olingo.server.api.processor;
-
-import org.apache.olingo.commons.api.format.ContentType;
-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.serializer.SerializerException;
-import org.apache.olingo.server.api.uri.UriInfo;
-
-/**
- * Processor interface for handling a single Entity.
- */
-public interface EntityProcessor extends Processor {
-
-  /**
-   * Reads entity data from persistence and puts serialized content and status into the response.
-   * @param request - OData request object containing raw HTTP information
-   * @param response - OData response object for collecting response data
-   * @param uriInfo - information of a parsed OData URI
-   * @param requestedContentType - requested content type after content negotiation
-   * @throws ODataApplicationException
-   * @throws SerializerException
-   */
-  void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
-      throws ODataApplicationException, SerializerException;
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntitySetProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntitySetProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntitySetProcessor.java
deleted file mode 100644
index fbb3faf..0000000
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntitySetProcessor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 org.apache.olingo.server.api.processor;
-
-import org.apache.olingo.commons.api.format.ContentType;
-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.serializer.SerializerException;
-import org.apache.olingo.server.api.uri.UriInfo;
-
-/**
- * Processor interface for handling EntitySets (i.e. collection of entities).
- */
-public interface EntitySetProcessor extends Processor {
-
-  /**
-   * Reads entities data from persistence and puts serialized content and status into the response.
-   * 
-   * @param request - OData request object containing raw HTTP information
-   * @param response - OData response object for collecting response data
-   * @param uriInfo - information of a parsed OData URI
-   * @param requestedContentType - requested content type after content negotiation
-   * @throws ODataApplicationException
-   * @throws SerializerException
-   */
-  void readEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
-      throws ODataApplicationException, SerializerException;
-
-  /**
-   * Count entities from persistence and puts serialized content and status into the response.
-   * Response content type is <code>text/plain</code> by default.
-   * 
-   * @param request - OData request object containing raw http information.
-   * @param response - OData response object for collecting response data
-   * @param uriInfo - information of a parsed OData uri
-   * @throws ODataApplicationException
-   * @throws SerializerException
-   */
-  void countEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException,
-      SerializerException;
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityTypeCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityTypeCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityTypeCollectionProcessor.java
new file mode 100644
index 0000000..71a4a3d
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityTypeCollectionProcessor.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.apache.olingo.server.api.processor;
+
+import org.apache.olingo.commons.api.format.ContentType;
+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.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * Processor interface for handling a collection of entities, e.g., an Entity Set.
+ */
+public interface EntityTypeCollectionProcessor extends Processor {
+
+  /**
+   * Reads entities data from persistence and puts serialized content and status into the response.
+   * 
+   * @param request - OData request object containing raw HTTP information
+   * @param response - OData response object for collecting response data
+   * @param uriInfo - information of a parsed OData URI
+   * @param requestedContentType - requested content type after content negotiation
+   * @throws ODataApplicationException
+   * @throws SerializerException
+   */
+  void readEntityTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
+      ContentType requestedContentType) throws ODataApplicationException, SerializerException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityTypeProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityTypeProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityTypeProcessor.java
new file mode 100644
index 0000000..28df774
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/EntityTypeProcessor.java
@@ -0,0 +1,44 @@
+/*
+ * 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 org.apache.olingo.server.api.processor;
+
+import org.apache.olingo.commons.api.format.ContentType;
+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.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * Processor interface for handling a single instance of an Entity Type.
+ */
+public interface EntityTypeProcessor extends Processor {
+
+  /**
+   * Reads entity data from persistence and puts serialized content and status into the response.
+   * @param request - OData request object containing raw HTTP information
+   * @param response - OData response object for collecting response data
+   * @param uriInfo - information of a parsed OData URI
+   * @param requestedContentType - requested content type after content negotiation
+   * @throws ODataApplicationException
+   * @throws SerializerException
+   */
+  void readEntityType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
+      throws ODataApplicationException, SerializerException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveTypeCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveTypeCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveTypeCollectionProcessor.java
new file mode 100644
index 0000000..42ccc4b
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveTypeCollectionProcessor.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.apache.olingo.server.api.processor;
+
+import org.apache.olingo.commons.api.format.ContentType;
+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.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * Processor interface for handling a collection of primitive-type instances, e.g.,
+ * a property of an entity defined as collection of primitive-type instances.
+ */
+public interface PrimitiveTypeCollectionProcessor extends Processor {
+
+  /**
+   * Reads primitive-type collection.
+   * If it is not available, for example due to permissions, the service responds with 404 Not Found.
+   * @param request  OData request object containing raw HTTP information
+   * @param response OData response object for collecting response data
+   * @param uriInfo  information of a parsed OData URI
+   * @param format   requested content type after content negotiation
+   * @throws ODataApplicationException if the service implementation encounters a failure
+   * @throws SerializerException       if serialization failed
+   */
+  void readPrimitiveTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+      throws ODataApplicationException, SerializerException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveTypeProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveTypeProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveTypeProcessor.java
new file mode 100644
index 0000000..ec2e81d
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PrimitiveTypeProcessor.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.apache.olingo.server.api.processor;
+
+import org.apache.olingo.commons.api.format.ContentType;
+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.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * Processor interface for handling a primitive type, e.g., a primitive property of an entity.
+ */
+public interface PrimitiveTypeProcessor extends Processor {
+
+  /**
+   * Reads primitive type.
+   * If its value is <code>null</code>, the service responds with 204 No Content.
+   * If it is not available, for example due to permissions, the service responds with 404 Not Found.
+   * @param request  OData request object containing raw HTTP information
+   * @param response OData response object for collecting response data
+   * @param uriInfo  information of a parsed OData URI
+   * @param format   requested content type after content negotiation
+   * @throws ODataApplicationException if the service implementation encounters a failure
+   * @throws SerializerException       if serialization failed
+   */
+  void readPrimitiveType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+      throws ODataApplicationException, SerializerException;
+
+  /**
+   * Reads raw value of a primitive type, e.g., of a primitive property of an entity.
+   * If the value is <code>null</code>, the service responds with 204 No Content.
+   * If it is not available, for example due to permissions, the service responds with 404 Not Found.
+   * @param request  OData request object containing raw HTTP information
+   * @param response OData response object for collecting response data
+   * @param uriInfo  information of a parsed OData URI
+   * @param format   requested content type after content negotiation
+   * @throws ODataApplicationException if the service implementation encounters a failure
+   * @throws SerializerException       if serialization failed
+   */
+  void readPrimitiveTypeAsValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+      throws ODataApplicationException, SerializerException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PropertyProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PropertyProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PropertyProcessor.java
deleted file mode 100644
index d0d0ee7..0000000
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/PropertyProcessor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 org.apache.olingo.server.api.processor;
-
-import org.apache.olingo.commons.api.format.ContentType;
-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.serializer.SerializerException;
-import org.apache.olingo.server.api.uri.UriInfo;
-
-/**
- * Processor interface for handling a property of an entity.
- */
-public interface PropertyProcessor extends Processor {
-
-  /**
-   * Reads primitive or complex property from entity.
-   * If the property is single-valued and has the null value, the service responds with 204 No Content.
-   * If the property is not available, for example due to permissions, the service responds with 404 Not Found
-   *
-   * @param request - OData request object containing raw HTTP information
-   * @param response - OData response object for collecting response data
-   * @param uriInfo - information of a parsed OData URI
-   * @param format - requested content type after content negotiation
-   * @throws ODataApplicationException if service implementation encounters a failure
-   * @throws SerializerException if serialization failed
-   */
-  void readProperty(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
-          throws ODataApplicationException, SerializerException;
-
-  /**
-   * Reads value for primitive property from entity.
-   * If the property is single-valued and has the null value, the service responds with 204 No Content.
-   * If the property is not available, for example due to permissions, the service responds with 404 Not Found
-   *
-   * @param request - OData request object containing raw HTTP information
-   * @param response - OData response object for collecting response data
-   * @param uriInfo - information of a parsed OData URI
-   * @param format - requested content type after content negotiation
-   * @throws ODataApplicationException if service implementation encounters a failure
-   * @throws SerializerException if serialization failed
-   */
-  void readPropertyValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
-          throws ODataApplicationException, SerializerException;
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index a13ef6f..1d90f55 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -35,20 +35,24 @@ import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.ODataServerError;
 import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.processor.ComplexTypeCollectionProcessor;
+import org.apache.olingo.server.api.processor.ComplexTypeProcessor;
+import org.apache.olingo.server.api.processor.CountEntityTypeCollectionProcessor;
 import org.apache.olingo.server.api.processor.DefaultProcessor;
-import org.apache.olingo.server.api.processor.EntitySetProcessor;
-import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.processor.EntityTypeCollectionProcessor;
+import org.apache.olingo.server.api.processor.EntityTypeProcessor;
 import org.apache.olingo.server.api.processor.ExceptionProcessor;
 import org.apache.olingo.server.api.processor.MetadataProcessor;
+import org.apache.olingo.server.api.processor.PrimitiveTypeCollectionProcessor;
+import org.apache.olingo.server.api.processor.PrimitiveTypeProcessor;
 import org.apache.olingo.server.api.processor.Processor;
-import org.apache.olingo.server.api.processor.PropertyProcessor;
 import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
 import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
 import org.apache.olingo.server.api.serializer.RepresentationType;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.UriInfo;
 import org.apache.olingo.server.api.uri.UriResource;
-import org.apache.olingo.server.api.uri.UriResourceKind;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
 import org.apache.olingo.server.api.uri.UriResourceNavigation;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
 import org.apache.olingo.server.api.uri.UriResourceProperty;
@@ -127,11 +131,10 @@ public class ODataHandler {
     switch (uriInfo.getKind()) {
     case metadata:
       if (method.equals(HttpMethod.GET)) {
-        MetadataProcessor mp = selectProcessor(MetadataProcessor.class);
-
-        ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
-            customContentTypeSupport, RepresentationType.METADATA);
-        mp.readMetadata(request, response, uriInfo, requestedContentType);
+        final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+            request, customContentTypeSupport, RepresentationType.METADATA);
+        selectProcessor(MetadataProcessor.class)
+            .readMetadata(request, response, uriInfo, requestedContentType);
       } else {
         throw new ODataHandlerException("HttpMethod " + method + " not allowed for metadata document",
             ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
@@ -140,15 +143,13 @@ public class ODataHandler {
     case service:
       if (method.equals(HttpMethod.GET)) {
         if ("".equals(request.getRawODataPath())) {
-          RedirectProcessor rdp = selectProcessor(RedirectProcessor.class);
-          rdp.redirect(request, response);
+          selectProcessor(RedirectProcessor.class).redirect(request, response);
         } else {
-          ServiceDocumentProcessor sdp = selectProcessor(ServiceDocumentProcessor.class);
-
-          ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
-              customContentTypeSupport, RepresentationType.SERVICE);
+          final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+              request, customContentTypeSupport, RepresentationType.SERVICE);
 
-          sdp.readServiceDocument(request, response, uriInfo, requestedContentType);
+          selectProcessor(ServiceDocumentProcessor.class)
+              .readServiceDocument(request, response, uriInfo, requestedContentType);
         }
       } else {
         throw new ODataHandlerException("HttpMethod " + method + " not allowed for service document",
@@ -185,113 +186,118 @@ public class ODataHandler {
 
   private void handleResourceDispatching(final ODataRequest request, final ODataResponse response)
       throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException, SerializerException {
+    final HttpMethod method = request.getMethod();
     final int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
-    UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
+    final UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
 
     switch (lastPathSegment.getKind()) {
     case entitySet:
+    case navigationProperty:
       if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
-        if (request.getMethod().equals(HttpMethod.GET)) {
-          EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
-
-          ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
-              customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
+        if (method.equals(HttpMethod.GET)) {
+          final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+              request, customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
 
-          cp.readEntitySet(request, response, uriInfo, requestedContentType);
+          selectProcessor(EntityTypeCollectionProcessor.class)
+              .readEntityTypeCollection(request, response, uriInfo, requestedContentType);
         } else {
           throw new ODataHandlerException("not implemented",
               ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
         }
       } else {
-        if (request.getMethod().equals(HttpMethod.GET)) {
-          EntityProcessor ep = selectProcessor(EntityProcessor.class);
+        if (method.equals(HttpMethod.GET)) {
+          final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+              request, customContentTypeSupport, RepresentationType.ENTITY);
 
-          ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
-              customContentTypeSupport, RepresentationType.ENTITY);
-
-          ep.readEntity(request, response, uriInfo, requestedContentType);
+          selectProcessor(EntityTypeProcessor.class)
+              .readEntityType(request, response, uriInfo, requestedContentType);
         } else {
           throw new ODataHandlerException("not implemented",
               ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
         }
       }
       break;
-    case navigationProperty:
-      if (((UriResourceNavigation) lastPathSegment).isCollection()) {
-        if (request.getMethod().equals(HttpMethod.GET)) {
-          EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
-
-          ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
-              customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
 
-          cp.readEntitySet(request, response, uriInfo, requestedContentType);
+    case count:
+      if (method.equals(HttpMethod.GET)) {
+        final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
+        if (resource instanceof UriResourceEntitySet || resource instanceof UriResourceNavigation) {
+          selectProcessor(CountEntityTypeCollectionProcessor.class)
+              .countEntityTypeCollection(request, response, uriInfo);
         } else {
-          throw new ODataHandlerException("not implemented",
+          throw new ODataHandlerException(
+              "Count of collections of primitive-type or complex-type instances is not implemented.",
               ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
         }
       } else {
-        if (request.getMethod().equals(HttpMethod.GET)) {
-          EntityProcessor ep = selectProcessor(EntityProcessor.class);
-
-          ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
-              customContentTypeSupport, RepresentationType.ENTITY);
+        throw new ODataHandlerException("HTTP method " + method + " is not allowed for count.",
+            ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
+      }
+      break;
 
-          ep.readEntity(request, response, uriInfo, requestedContentType);
+    case primitiveProperty:
+      if (method.equals(HttpMethod.GET)) {
+        final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment;
+        final RepresentationType representationType = propertyResource.isCollection() ?
+            RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE;
+        final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+            request, customContentTypeSupport, representationType);
+        if (representationType == RepresentationType.PRIMITIVE) {
+          selectProcessor(PrimitiveTypeProcessor.class)
+              .readPrimitiveType(request, response, uriInfo, requestedContentType);
         } else {
-          throw new ODataHandlerException("not implemented",
-              ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+          selectProcessor(PrimitiveTypeCollectionProcessor.class)
+              .readPrimitiveTypeCollection(request, response, uriInfo, requestedContentType);
         }
-      }
-      break;
-    case count:
-      if (request.getMethod().equals(HttpMethod.GET)) {
-        EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
-        cp.countEntitySet(request, response, uriInfo);
       } else {
         throw new ODataHandlerException("not implemented",
             ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
       }
       break;
-    case primitiveProperty:
-    case complexProperty:
-      if (request.getMethod().equals(HttpMethod.GET)) {
-        PropertyProcessor ep = selectProcessor(PropertyProcessor.class);
 
+    case complexProperty:
+      if (method.equals(HttpMethod.GET)) {
         final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment;
-        final boolean isCollection = propertyResource.isCollection();
-        final boolean isComplex = propertyResource.getKind() == UriResourceKind.complexProperty;
-        final RepresentationType representationType =
-            isComplex ? isCollection ? RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX :
-                isCollection ? RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE;
-        ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
-            customContentTypeSupport, representationType);
-
-        ep.readProperty(request, response, uriInfo, requestedContentType);
+        final RepresentationType representationType = propertyResource.isCollection() ?
+            RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX;
+        final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+            request, customContentTypeSupport, representationType);
+        if (representationType == RepresentationType.COMPLEX) {
+          selectProcessor(ComplexTypeProcessor.class)
+              .readComplexType(request, response, uriInfo, requestedContentType);
+        } else {
+          selectProcessor(ComplexTypeCollectionProcessor.class)
+              .readComplexTypeCollection(request, response, uriInfo, requestedContentType);
+        }
       } else {
         throw new ODataHandlerException("not implemented",
             ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
       }
       break;
-    case value:
-      if (request.getMethod().equals(HttpMethod.GET)) {
-        PropertyProcessor ep = selectProcessor(PropertyProcessor.class);
-
-        final UriResourceProperty propertyResource =
-            (UriResourceProperty) uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
-        final RepresentationType representationType =
-            (EdmPrimitiveType) propertyResource.getType() ==
-            EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
-                RepresentationType.BINARY :
-                RepresentationType.VALUE;
-        ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
-            customContentTypeSupport, representationType);
 
-        ep.readPropertyValue(request, response, uriInfo, requestedContentType);
+    case value:
+      if (method.equals(HttpMethod.GET)) {
+        final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
+        if (resource instanceof UriResourceProperty) {
+          final RepresentationType representationType =
+              (EdmPrimitiveType) ((UriResourceProperty) resource).getType() ==
+              EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
+                  RepresentationType.BINARY : RepresentationType.VALUE;
+          final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+              request, customContentTypeSupport, representationType);
+
+          selectProcessor(PrimitiveTypeProcessor.class)
+              .readPrimitiveTypeAsValue(request, response, uriInfo, requestedContentType);
+        } else {
+          throw new ODataHandlerException("Media Entity is not implemented.",
+              ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+        }
       } else {
         throw new ODataHandlerException("not implemented",
             ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
       }
       break;
+
     default:
       throw new ODataHandlerException("not implemented",
           ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
index 40ceee9..78c9caa 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
@@ -24,7 +24,8 @@ import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
 import org.apache.olingo.server.tecsvc.data.DataProvider;
-import org.apache.olingo.server.tecsvc.processor.TechnicalProcessor;
+import org.apache.olingo.server.tecsvc.processor.TechnicalEntityProcessor;
+import org.apache.olingo.server.tecsvc.processor.TechnicalPrimitiveComplexProcessor;
 import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -64,7 +65,8 @@ public class TechnicalServlet extends HttpServlet {
       }
 
       ODataHttpHandler handler = odata.createHandler(serviceMetadata);
-      handler.register(new TechnicalProcessor(dataProvider));
+      handler.register(new TechnicalEntityProcessor(dataProvider));
+      handler.register(new TechnicalPrimitiveComplexProcessor(dataProvider));
       handler.process(req, resp);
     } catch (RuntimeException e) {
       LOG.error("Server Error", e);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
new file mode 100644
index 0000000..1873629
--- /dev/null
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -0,0 +1,163 @@
+/*
+ * 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 org.apache.olingo.server.tecsvc.processor;
+
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import java.util.Locale;
+
+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.EntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+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.processor.CountEntityTypeCollectionProcessor;
+import org.apache.olingo.server.api.processor.EntityTypeCollectionProcessor;
+import org.apache.olingo.server.api.processor.EntityTypeProcessor;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+import org.apache.olingo.server.tecsvc.data.DataProvider;
+
+/**
+ * Technical Processor for entity-related functionality.
+ */
+public class TechnicalEntityProcessor extends TechnicalProcessor
+    implements EntityTypeCollectionProcessor, CountEntityTypeCollectionProcessor, EntityTypeProcessor {
+
+  public TechnicalEntityProcessor(final DataProvider dataProvider) {
+    super(dataProvider);
+  }
+
+  @Override
+  public void readEntityTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+      final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
+    validateOptions(uriInfo.asUriInfoResource());
+    if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
+      throw new ODataApplicationException("Invalid resource type.",
+          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+    }
+
+    final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
+    final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
+        uriInfo.getCountOption() != null && uriInfo.getCountOption().getValue());
+    if (entitySet == null) {
+      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+    } else {
+      final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
+      ODataSerializer serializer = odata.createSerializer(format);
+      final ExpandOption expand = uriInfo.getExpandOption();
+      final SelectOption select = uriInfo.getSelectOption();
+      response.setContent(serializer.entitySet(edmEntitySet, entitySet,
+          ODataSerializerOptions.with()
+              .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
+                  getContextUrl(serializer, edmEntitySet, false, expand, select))
+              .count(uriInfo.getCountOption())
+              .expand(expand).select(select)
+              .build()));
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+    }
+  }
+
+  @Override
+  public void countEntityTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
+      throws ODataApplicationException, SerializerException {
+    validateOptions(uriInfo.asUriInfoResource());
+    final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
+    final int pos = resourceParts.size() - 2;
+    if (pos > 0) {
+      throw new ODataApplicationException("Invalid resource type.",
+          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+    }
+    final EntitySet entitySet =
+        readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
+    if (entitySet == null) {
+      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+    } else {
+      response.setContent(new ByteArrayInputStream(entitySet.getCount().toString().getBytes()));
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE, HttpContentType.TEXT_PLAIN);
+    }
+  }
+
+  @Override
+  public void readEntityType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+      final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
+    validateOptions(uriInfo.asUriInfoResource());
+    if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
+      throw new ODataApplicationException("Invalid resource type.",
+          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+    }
+
+    final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
+    final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
+    final Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates());
+
+    if (entity == null) {
+      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+    } else {
+      final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
+      ODataSerializer serializer = odata.createSerializer(format);
+      final ExpandOption expand = uriInfo.getExpandOption();
+      final SelectOption select = uriInfo.getSelectOption();
+      response.setContent(serializer.entity(edmEntitySet, entity,
+          ODataSerializerOptions.with()
+              .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
+                  getContextUrl(serializer, edmEntitySet, true, expand, select))
+              .count(uriInfo.getCountOption())
+              .expand(expand).select(select)
+              .build()));
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+    }
+  }
+
+  private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet, final boolean withCount)
+      throws DataProvider.DataProviderException {
+    EntitySet entitySet = dataProvider.readAll(edmEntitySet);
+    // TODO: set count (correctly) and next link
+    if (withCount && entitySet.getCount() == null) {
+      entitySet.setCount(entitySet.getEntities().size());
+    }
+    return entitySet;
+  }
+
+  private ContextURL getContextUrl(final ODataSerializer serializer,
+      final EdmEntitySet entitySet, final boolean isSingleEntity,
+      final ExpandOption expand, final SelectOption select) throws SerializerException {
+    return ContextURL.with().entitySet(entitySet)
+        .selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
+        .suffix(isSingleEntity ? Suffix.ENTITY : null)
+        .build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
new file mode 100644
index 0000000..9666f6d
--- /dev/null
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
@@ -0,0 +1,224 @@
+/*
+ * 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 org.apache.olingo.server.tecsvc.processor;
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+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.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+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.processor.ComplexTypeCollectionProcessor;
+import org.apache.olingo.server.api.processor.ComplexTypeProcessor;
+import org.apache.olingo.server.api.processor.PrimitiveTypeCollectionProcessor;
+import org.apache.olingo.server.api.processor.PrimitiveTypeProcessor;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+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.UriResourceKind;
+import org.apache.olingo.server.api.uri.UriResourceProperty;
+import org.apache.olingo.server.tecsvc.data.DataProvider;
+
+/**
+ * Technical Processor which provides functionality related to primitive and complex types and collections thereof.
+ */
+public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
+    implements PrimitiveTypeProcessor, PrimitiveTypeCollectionProcessor,
+    ComplexTypeProcessor, ComplexTypeCollectionProcessor {
+
+  public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider) {
+    super(dataProvider);
+  }
+
+  @Override
+  public void readPrimitiveType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+      final ContentType contentType) throws ODataApplicationException, SerializerException {
+    readProperty(response, uriInfo, contentType);
+  }
+
+  @Override
+  public void readPrimitiveTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+      final ContentType contentType) throws ODataApplicationException, SerializerException {
+    readProperty(response, uriInfo, contentType);
+  }
+
+  @Override
+  public void readComplexType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+      final ContentType contentType) throws ODataApplicationException, SerializerException {
+    readProperty(response, uriInfo, contentType);
+  }
+
+  @Override
+  public void readComplexTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+      final ContentType contentType) throws ODataApplicationException, SerializerException {
+    readProperty(response, uriInfo, contentType);
+  }
+
+  private void readProperty(ODataResponse response, final UriInfo uriInfo, final ContentType contentType)
+      throws ODataApplicationException, SerializerException {
+    final UriInfoResource resource = uriInfo.asUriInfoResource();
+    validateOptions(resource);
+    validatePath(resource);
+
+    final List<UriResource> resourceParts = resource.getUriResourceParts();
+    final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
+    final List<String> path = getPropertyPath(resourceParts);
+
+    final Property property = getPropertyData(resourceEntitySet, path);
+
+    if (property == null) {
+      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+    } else {
+      if (property.getValue() == null) {
+        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+      } else {
+        final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
+        final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
+
+        final ODataFormat format = ODataFormat.fromContentType(contentType);
+        ODataSerializer serializer = odata.createSerializer(format);
+        response.setContent(serializer.entityProperty(edmProperty, property,
+            ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
+                ContextURL.with().entitySet(edmEntitySet)
+                    .keyPath(serializer.buildContextURLKeyPredicate(
+                        ((UriResourceEntitySet) resourceParts.get(0)).getKeyPredicates()))
+                    .navOrPropertyPath(buildPropertyPath(path))
+                    .build())
+                .build()));
+        response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+        response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
+      }
+    }
+  }
+
+  private Property getPropertyData(final UriResourceEntitySet resourceEntitySet, final List<String> path)
+      throws ODataApplicationException {
+    final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates());
+    if (entity == null) {
+      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+    } else {
+      Property property = entity.getProperty(path.get(0));
+      for (final String name : path.subList(1, path.size())) {
+        if (property != null && (property.isLinkedComplex() || property.isComplex())) {
+          final List<Property> complex = property.isLinkedComplex() ?
+              property.asLinkedComplex().getValue() : property.asComplex();
+          property = null;
+          for (final Property innerProperty : complex) {
+            if (innerProperty.getName().equals(name)) {
+              property = innerProperty;
+              break;
+            }
+          }
+        }
+      }
+      return property;
+    }
+  }
+
+  private List<String> getPropertyPath(final List<UriResource> path) {
+    List<String> result = new LinkedList<String>();
+    int index = 1;
+    while (index < path.size() && path.get(index) instanceof UriResourceProperty) {
+      result.add(((UriResourceProperty) path.get(index)).getProperty().getName());
+      index++;
+    }
+    return result;
+  }
+
+  private String buildPropertyPath(final List<String> path) {
+    StringBuilder result = new StringBuilder();
+    for (final String segment : path) {
+      result.append(result.length() == 0 ? "" : '/').append(segment);
+    }
+    return result.toString();
+  }
+
+  @Override
+  public void readPrimitiveTypeAsValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
+      final ContentType contentType) throws ODataApplicationException, SerializerException {
+    final UriInfoResource resource = uriInfo.asUriInfoResource();
+    validateOptions(resource);
+    validatePath(resource);
+
+    final List<UriResource> resourceParts = resource.getUriResourceParts();
+    final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
+    final List<String> path = getPropertyPath(resourceParts);
+
+    final Property property = getPropertyData(resourceEntitySet, path);
+
+    if (property == null || property.getValue() == null) {
+      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    } else {
+      final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
+      final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
+      if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)) {
+        response.setContent(new ByteArrayInputStream((byte[]) property.getValue()));
+      } else {
+        try {
+          final String value = type.valueToString(property.getValue(),
+              edmProperty.isNullable(), edmProperty.getMaxLength(),
+              edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
+          response.setContent(new ByteArrayInputStream(value.getBytes("UTF-8")));
+        } catch (final EdmPrimitiveTypeException e) {
+          throw new ODataApplicationException("Error in value formatting.",
+              HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
+        } catch (final UnsupportedEncodingException e) {
+          throw new ODataApplicationException("Encoding exception.",
+              HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
+        }
+      }
+      response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    }
+  }
+
+  private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException {
+    final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+    for (final UriResource segment : resourcePaths.subList(1, resourcePaths.size())) {
+      final UriResourceKind kind = segment.getKind();
+      if (kind != UriResourceKind.primitiveProperty
+          && kind != UriResourceKind.complexProperty
+          && kind != UriResourceKind.count
+          && kind != UriResourceKind.value) {
+        throw new ODataApplicationException("Invalid resource type.",
+            HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a405e5b4/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index d88a02f..62c0140 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@ -18,60 +18,29 @@
  */
 package org.apache.olingo.server.tecsvc.processor;
 
-import java.io.ByteArrayInputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 
-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.EntitySet;
-import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.edm.EdmComplexType;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-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.HttpContentType;
-import org.apache.olingo.commons.api.http.HttpHeader;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 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.EntityProcessor;
-import org.apache.olingo.server.api.processor.EntitySetProcessor;
-import org.apache.olingo.server.api.processor.PropertyProcessor;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
-import org.apache.olingo.server.api.serializer.SerializerException;
-import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.processor.Processor;
 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;
-import org.apache.olingo.server.api.uri.UriResourceKind;
-import org.apache.olingo.server.api.uri.UriResourceProperty;
-import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
-import org.apache.olingo.server.api.uri.queryoption.SelectOption;
 import org.apache.olingo.server.tecsvc.data.DataProvider;
 
 /**
- * Technical Processor which provides currently implemented processor functionality.
+ * Technical Processor base.
  */
-public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor {
+public abstract class TechnicalProcessor implements Processor {
 
-  private OData odata;
-  private DataProvider dataProvider;
+  protected OData odata;
+  protected DataProvider dataProvider;
 
-  public TechnicalProcessor(final DataProvider dataProvider) {
+  protected TechnicalProcessor(final DataProvider dataProvider) {
     this.dataProvider = dataProvider;
   }
 
@@ -80,92 +49,23 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
     this.odata = odata;
   }
 
-  @Override
-  public void readEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
-      final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
-    validateOptions(uriInfo.asUriInfoResource());
-
-    final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
-    final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
-        uriInfo.getCountOption() != null && uriInfo.getCountOption().getValue());
-    if (entitySet == null) {
-      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
-    } else {
-      final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
-      ODataSerializer serializer = odata.createSerializer(format);
-      final ExpandOption expand = uriInfo.getExpandOption();
-      final SelectOption select = uriInfo.getSelectOption();
-      response.setContent(serializer.entitySet(edmEntitySet, entitySet,
-          ODataSerializerOptions.with()
-              .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
-                  getContextUrl(serializer, edmEntitySet, false, expand, select, null, null))
-              .count(uriInfo.getCountOption())
-              .expand(expand).select(select)
-              .build()));
-      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-      response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
-    }
-  }
-
-  @Override
-  public void readEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
-      final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
-    validateOptions(uriInfo.asUriInfoResource());
-
-    final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
-    final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
-    if (entity == null) {
-      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
-    } else {
-      final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
-      ODataSerializer serializer = odata.createSerializer(format);
-      final ExpandOption expand = uriInfo.getExpandOption();
-      final SelectOption select = uriInfo.getSelectOption();
-      response.setContent(serializer.entity(edmEntitySet, entity,
-          ODataSerializerOptions.with()
-              .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
-                  getContextUrl(serializer, edmEntitySet, true, expand, select, null, null))
-              .count(uriInfo.getCountOption())
-              .expand(expand).select(select)
-              .build()));
-      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-      response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
-    }
-  }
-
-  @Override
-  public void countEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
-      throws ODataApplicationException, SerializerException {
-    final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
-    final int pos = resourceParts.size() - 2;
-    final EntitySet entitySet =
-        readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
-    if (entitySet == null) {
-      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
-    } else {
-      response.setContent(new ByteArrayInputStream(entitySet.getCount().toString().getBytes()));
-      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-      response.setHeader(HttpHeader.CONTENT_TYPE, HttpContentType.TEXT_PLAIN);
+  protected EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
+    final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+    // first must be entity set
+    if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
+      throw new ODataApplicationException("Invalid resource type.",
+          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
     }
-  }
 
-  private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet,
-      final boolean withCount) throws DataProvider.DataProviderException {
-    EntitySet entitySet = dataProvider.readAll(edmEntitySet);
-    // TODO: set count (correctly) and next link
-    if (withCount && entitySet.getCount() == null) {
-      entitySet.setCount(entitySet.getEntities().size());
+    final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
+    if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) {
+      throw new ODataApplicationException("Type filters are not supported.",
+          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
     }
-    return entitySet;
-  }
-
-  private Entity readEntityInternal(final UriInfoResource uriInfo, final EdmEntitySet entitySet)
-      throws DataProvider.DataProviderException {
-    final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
-    return dataProvider.read(entitySet, resourceEntitySet.getKeyPredicates());
+    return uriResource.getEntitySet();
   }
 
-  private void validateOptions(final UriInfoResource uriInfo) throws ODataApplicationException {
+  protected void validateOptions(final UriInfoResource uriInfo) throws ODataApplicationException {
     if (uriInfo.getCountOption() != null
         || !uriInfo.getCustomQueryOptions().isEmpty()
         || uriInfo.getFilterOption() != null
@@ -179,151 +79,4 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
           HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
     }
   }
-
-  private EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
-    final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
-    // first must be entity set
-    if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
-      throw new ODataApplicationException("Invalid resource type.",
-          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
-    }
-    List<UriResource> subResPaths = resourcePaths.subList(1, resourcePaths.size());
-    for (UriResource subResPath : subResPaths) {
-      UriResourceKind kind = subResPath.getKind();
-      if(kind != UriResourceKind.primitiveProperty
-              && kind != UriResourceKind.complexProperty
-              && kind != UriResourceKind.count
-              && kind != UriResourceKind.value) {
-        throw new ODataApplicationException("Invalid resource type.",
-                HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
-      }
-    }
-
-    final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
-    if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) {
-      throw new ODataApplicationException("Type filters are not supported.",
-          HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
-    }
-    return uriResource.getEntitySet();
-  }
-
-  private ContextURL getContextUrl(final ODataSerializer serializer,
-      final EdmEntitySet entitySet, final boolean isSingleEntity,
-      final ExpandOption expand, final SelectOption select,
-      final List<UriParameter> keys, final String propertyPath) throws SerializerException {
-    return ContextURL.with().entitySet(entitySet)
-        .selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
-        .suffix(isSingleEntity && propertyPath == null ? Suffix.ENTITY : null)
-        .keyPath(serializer.buildContextURLKeyPredicate(keys))
-        .navOrPropertyPath(propertyPath)
-        .build();
-  }
-
-  @Override
-  public void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
-      final ContentType contentType) throws ODataApplicationException, SerializerException {
-    validateOptions(uriInfo.asUriInfoResource());
-
-    final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
-    final List<UriResource> resourceParts = uriInfo.getUriResourceParts();
-    final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
-    final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
-
-    if (entity == null) {
-      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
-    } else {
-      final List<String> path = getPropertyPath(resourceParts);
-      EdmProperty edmProperty = edmEntitySet.getEntityType().getStructuralProperty(path.get(0));
-      Property property = entity.getProperty(path.get(0));
-      for (final String name : path.subList(1, path.size())) {
-        if (property != null && (property.isLinkedComplex() || property.isComplex())) {
-          edmProperty = ((EdmComplexType) edmProperty.getType()).getStructuralProperty(name);
-          final List<Property> complex = property.isLinkedComplex() ?
-              property.asLinkedComplex().getValue() :
-              property.asComplex();
-          property = null;
-          for (final Property innerProperty : complex) {
-            if (innerProperty.getName().equals(name)) {
-              property = innerProperty;
-              break;
-            }
-          }
-        }
-      }
-      if (property == null) {
-        throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
-      } else {
-        if (property.getValue() == null) {
-          response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
-        } else {
-          final ODataFormat format = ODataFormat.fromContentType(contentType);
-          ODataSerializer serializer = odata.createSerializer(format);
-          response.setContent(serializer.entityProperty(edmProperty, property,
-              ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
-                  getContextUrl(serializer, edmEntitySet, true, null, null,
-                      resourceEntitySet.getKeyPredicates(), buildPropertyPath(path)))
-                  .build()));
-          response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-          response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
-        }
-      }
-    }
-  }
-
-  private List<String> getPropertyPath(final List<UriResource> path) {
-    List<String> result = new LinkedList<String>();
-    int index = path.size();
-    while (path.get(--index) instanceof UriResourceProperty) {
-      result.add(0, ((UriResourceProperty) path.get(index)).getProperty().getName());
-    }
-    return result;
-  }
-
-  private String buildPropertyPath(final List<String> path) {
-    StringBuilder result = new StringBuilder();
-    for (final String segment : path) {
-      result.append(result.length() == 0 ? "" : '/').append(segment);
-    }
-    return result.toString();
-  }
-
-  @Override
-  public void readPropertyValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
-      final ContentType contentType) throws ODataApplicationException, SerializerException {
-    validateOptions(uriInfo.asUriInfoResource());
-
-    final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
-    final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
-    if (entity == null) {
-      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
-    } else {
-      final UriResourceProperty uriProperty =
-          (UriResourceProperty) uriInfo.getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 2);
-      final EdmProperty edmProperty = uriProperty.getProperty();
-      final Property property = entity.getProperty(edmProperty.getName());
-      if (property == null || property.getValue() == null) {
-        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
-      } else {
-        final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
-        if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)) {
-          response.setContent(new ByteArrayInputStream((byte[]) property.getValue()));
-        } else {
-          try {
-            final String value = type.valueToString(property.getValue(),
-                edmProperty.isNullable(), edmProperty.getMaxLength(),
-                edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
-            response.setContent(new ByteArrayInputStream(value.getBytes("UTF-8")));
-          } catch (final EdmPrimitiveTypeException e) {
-            throw new ODataApplicationException("Error in value formatting.",
-                HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
-          } catch (final UnsupportedEncodingException e) {
-            throw new ODataApplicationException("Encoding exception.",
-                HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
-          }
-        }
-        response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
-        response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-      }
-    }
-  }
 }