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 2015/04/04 19:05:29 UTC

[23/50] [abbrv] olingo-odata4 git commit: OLINGO-573: New processing framework on server side with single interface with TripPin example

OLINGO-573: New processing framework on server side with single interface with TripPin example


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

Branch: refs/heads/OLINGO-549-ODataV4-JPA
Commit: 8668b097192674b47ba48e8978633665858f5d32
Parents: 62f1001
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Mon Mar 30 12:40:32 2015 -0500
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Mon Mar 30 12:40:32 2015 -0500

----------------------------------------------------------------------
 .../ExpandWithSystemQueryOptionsITCase.java     |  65 +-
 .../apache/olingo/commons/core/DecoderTest.java |  10 +-
 .../apache/olingo/commons/core/EncoderTest.java |  10 +-
 lib/pom.xml                                     |   1 +
 .../api/deserializer/ODataDeserializer.java     |  31 +-
 .../EntityCollectionSerializerOptions.java      |  18 +-
 .../api/serializer/EntitySerializerOptions.java |  18 +-
 .../server/api/serializer/ODataSerializer.java  |  26 +-
 .../api/serializer/SerializerException.java     |   8 +-
 lib/server-core-ext/pom.xml                     | 117 +++
 .../apache/olingo/server/core/ErrorHandler.java | 125 +++
 .../olingo/server/core/MetadataParser.java      | 679 +++++++++++++++
 .../olingo/server/core/OData4HttpHandler.java   | 123 +++
 .../apache/olingo/server/core/OData4Impl.java   |  45 +
 .../server/core/RequestURLHierarchyVisitor.java | 333 ++++++++
 .../olingo/server/core/RequestURLVisitor.java   | 127 +++
 .../server/core/ReturnRepresentation.java       |  23 +
 .../server/core/SchemaBasedEdmProvider.java     | 303 +++++++
 .../olingo/server/core/ServiceDispatcher.java   | 227 +++++
 .../olingo/server/core/ServiceHandler.java      | 263 ++++++
 .../olingo/server/core/ServiceRequest.java      | 253 ++++++
 .../core/legacy/ProcessorServiceHandler.java    | 433 ++++++++++
 .../server/core/requests/ActionRequest.java     | 120 +++
 .../server/core/requests/BatchRequest.java      | 197 +++++
 .../server/core/requests/DataRequest.java       | 769 +++++++++++++++++
 .../server/core/requests/FunctionRequest.java   | 122 +++
 .../server/core/requests/MediaRequest.java      |  99 +++
 .../server/core/requests/MetadataRequest.java   |  61 ++
 .../server/core/requests/OperationRequest.java  | 118 +++
 .../core/requests/ServiceDocumentRequest.java   |  57 ++
 .../server/core/responses/CountResponse.java    |  60 ++
 .../server/core/responses/EntityResponse.java   | 140 +++
 .../core/responses/EntitySetResponse.java       |  82 ++
 .../server/core/responses/MetadataResponse.java |  62 ++
 .../core/responses/NoContentResponse.java       | 100 +++
 .../core/responses/PrimitiveValueResponse.java  | 105 +++
 .../server/core/responses/PropertyResponse.java | 144 ++++
 .../core/responses/ServiceDocumentResponse.java |  63 ++
 .../server/core/responses/ServiceResponse.java  | 119 +++
 .../core/responses/ServiceResponseVisior.java   |  71 ++
 .../server/core/responses/StreamResponse.java   |  54 ++
 .../olingo/server/core/MetadataParserTest.java  | 185 ++++
 .../server/core/ServiceDispatcherTest.java      | 417 +++++++++
 .../olingo/server/example/TripPinDataModel.java | 843 +++++++++++++++++++
 .../olingo/server/example/TripPinHandler.java   | 546 ++++++++++++
 .../server/example/TripPinServiceTest.java      | 756 +++++++++++++++++
 .../olingo/server/example/TripPinServlet.java   |  75 ++
 .../src/test/resources/OlingoOrangeTM.png       | Bin 0 -> 93316 bytes
 .../src/test/resources/airlines.json            |  64 ++
 .../src/test/resources/airports.json            | 394 +++++++++
 .../src/test/resources/event.json               | 157 ++++
 .../src/test/resources/flight-links.json        |  52 ++
 .../src/test/resources/flight.json              |  66 ++
 .../src/test/resources/people-links.json        |  94 +++
 .../src/test/resources/people.json              | 323 +++++++
 .../src/test/resources/photos.json              |  64 ++
 .../src/test/resources/trip-links.json          |  28 +
 .../src/test/resources/trip.json                | 224 +++++
 .../src/test/resources/trippin.xml              | 356 ++++++++
 .../json/ODataJsonDeserializer.java             |  86 +-
 .../serializer/json/ODataJsonSerializer.java    | 138 ++-
 .../serializer/utils/ContextURLBuilder.java     |   9 +-
 .../serializer/xml/ODataXmlSerializerImpl.java  |  19 +-
 .../server/core/uri/UriResourceActionImpl.java  |  14 +-
 .../server/core/uri/validator/UriValidator.java |   8 +-
 .../server-core-exceptions-i18n.properties      |   2 +
 .../json/ODataJsonDeserializerBasicTest.java    |  38 +-
 .../json/ODataJsonSerializerTest.java           |  13 +-
 .../olingo/server/tecsvc/TechnicalServlet.java  |   8 +-
 .../olingo/server/tecsvc/data/DataCreator.java  | 134 ++-
 .../olingo/server/tecsvc/data/DataProvider.java |  31 +-
 .../olingo/server/tecsvc/data/FunctionData.java |   7 +-
 .../processor/TechnicalEntityProcessor.java     |  28 +-
 .../TechnicalPrimitiveComplexProcessor.java     |  15 +-
 .../server/tecsvc/data/DataProviderTest.java    |   2 +-
 .../json/ODataJsonDeserializerEntityTest.java   |   4 +-
 .../json/ODataJsonSerializerTest.java           |  60 +-
 .../core/uri/antlr/TestUriParserImpl.java       |  11 +-
 .../core/uri/validator/UriValidatorTest.java    |  18 +-
 .../olingo/server/sample/data/DataProvider.java |  13 +-
 .../server/sample/processor/CarsProcessor.java  |  16 +-
 81 files changed, 10840 insertions(+), 259 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
index 2db9535..e5ad3ca 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
@@ -6,9 +6,9 @@
  * 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
@@ -69,13 +69,16 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
           entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
 
       if (propInt16.equals(1) && propString.equals("1")) {
-        assertEquals(1, inlineEntitySet.getEntities().size());
-        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
-
-        assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
-        assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+        assertEquals(2, inlineEntitySet.getEntities().size());
+        for (ODataEntity e:inlineEntitySet.getEntities()) {
+          assertEquals(1, e.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+          String strValue = (String)e.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+          if (!strValue.equals("2") && !strValue.equals("1")) {
+            fail();
+          }
+        }
       } else if (propInt16.equals(1) && propString.equals("2")) {
-        assertEquals(0, inlineEntitySet.getEntities().size());
+        assertEquals(1, inlineEntitySet.getEntities().size());
       } else if (propInt16.equals(2) && propString.equals("1")) {
         assertEquals(1, inlineEntitySet.getEntities().size());
         final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
@@ -108,14 +111,13 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
 
       if (propInt16.equals(1) && propString.equals("1")) {
         assertEquals(2, inlineEntitySet.getEntities().size());
-        final ODataEntity inlineEntity1 = inlineEntitySet.getEntities().get(0);
-        final ODataEntity inlineEntity2 = inlineEntitySet.getEntities().get(1);
-
-        assertEquals(1, inlineEntity1.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
-        assertEquals("2", inlineEntity1.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
-
-        assertEquals(1, inlineEntity2.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
-        assertEquals("1", inlineEntity2.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+        for (ODataEntity e:inlineEntitySet.getEntities()) {
+          assertEquals(1, e.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+          String strValue = (String)e.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+          if (!strValue.equals("2") && !strValue.equals("1")) {
+            fail();
+          }
+        }
       }
     }
   }
@@ -136,15 +138,15 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
           entity.getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
 
       if (propInt16.equals(1)) {
-        assertEquals(1, inlineEntitySet.getEntities().size());
+        assertEquals(2, inlineEntitySet.getEntities().size());
         final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
 
-        assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+        assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
       } else if (propInt16.equals(2)) {
-        assertEquals(1, inlineEntitySet.getEntities().size());
+        assertEquals(2, inlineEntitySet.getEntities().size());
         final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
 
-        assertEquals(3, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+        assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
       } else if (propInt16.equals(3)) {
         assertEquals(0, inlineEntitySet.getEntities().size());
       }
@@ -167,12 +169,12 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
           entity.getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
 
       if (propInt16.equals(1)) {
-        assertEquals(1, inlineEntitySet.getEntities().size());
+        assertEquals(2, inlineEntitySet.getEntities().size());
         final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
 
         assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
       } else if (propInt16.equals(2)) {
-        assertEquals(1, inlineEntitySet.getEntities().size());
+        assertEquals(2, inlineEntitySet.getEntities().size());
         final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
 
         assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
@@ -201,15 +203,18 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
           entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
 
       if (propInt16.equals(1) && propString.equals("1")) {
-        assertEquals(1, inlineEntitySet.getEntities().size());
-        final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
-
-        assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
-        assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+        assertEquals(2, inlineEntitySet.getEntities().size());
+        for (ODataEntity e:inlineEntitySet.getEntities()) {
+          assertEquals(1, e.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+          String strValue = (String)e.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+          if (!strValue.equals("2") && !strValue.equals("1")) {
+            fail();
+          }
+        }
       } else if (propInt16.equals(1) && propString.equals("2")) {
-        assertEquals(0, inlineEntitySet.getEntities().size());
+        assertEquals(1, inlineEntitySet.getEntities().size());
       } else if (propInt16.equals(2) && propString.equals("1")) {
-        assertEquals(0, inlineEntitySet.getEntities().size());
+        assertEquals(1, inlineEntitySet.getEntities().size());
       } else if (propInt16.equals(3) && propString.equals("1")) {
         assertEquals(0, inlineEntitySet.getEntities().size());
       } else {
@@ -274,7 +279,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
 
     final ODataEntitySet entitySet =
         response.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
-    assertEquals(1, entitySet.getEntities().size());
+    assertEquals(2, entitySet.getEntities().size());
     assertEquals(1, entitySet.getEntities().get(0).getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java
index 019ef5a..09f2326 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java
@@ -6,9 +6,9 @@
  * 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
@@ -18,13 +18,13 @@
  ******************************************************************************/
 package org.apache.olingo.commons.core;
 
-import org.junit.Test;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
+import org.junit.Test;
+
 /**
- *  
+ *
  */
 public class DecoderTest {
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java
index 74eb1af..7db30ce 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java
@@ -6,9 +6,9 @@
  * 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
@@ -18,16 +18,16 @@
  ******************************************************************************/
 package org.apache.olingo.commons.core;
 
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
 
 import java.net.URI;
 import java.net.URISyntaxException;
 
-import static org.junit.Assert.assertEquals;
+import org.junit.Test;
 
 /**
  * Tests for percent-encoding.
- * 
+ *
  */
 public class EncoderTest {
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/pom.xml
----------------------------------------------------------------------
diff --git a/lib/pom.xml b/lib/pom.xml
index 6843ff3..d1e8864 100644
--- a/lib/pom.xml
+++ b/lib/pom.xml
@@ -42,6 +42,7 @@
     <module>client-core</module>
     <module>server-api</module>
     <module>server-core</module>
+    <module>server-core-ext</module>
     <module>server-tecsvc</module>
     <module>server-test</module>
   </modules>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java
index d5f7343..3bbcc66 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java
@@ -6,9 +6,9 @@
  * 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
@@ -19,11 +19,15 @@
 package org.apache.olingo.server.api.deserializer;
 
 import java.io.InputStream;
+import java.net.URI;
+import java.util.List;
 
 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.EdmAction;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmProperty;
 
 /**
  * Deserializer on OData server side.
@@ -32,7 +36,7 @@ public interface ODataDeserializer {
 
   /**
    * Deserializes an entity stream into an {@link Entity} object.
-   * Validates: property types, no double properties, correct json types 
+   * Validates: property types, no double properties, correct json types
    * @param stream
    * @param edmEntityType
    * @return deserialized {@link Entity} object
@@ -48,7 +52,7 @@ public interface ODataDeserializer {
    * @throws DeserializerException
    */
   EntitySet entityCollection(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException;
-  
+
   /**
    * Deserializes an action-parameters stream into an {@link Entity} object.
    * Validates: parameter types, no double parameters, correct json types.
@@ -58,4 +62,23 @@ public interface ODataDeserializer {
    * @throws DeserializerException
    */
   Entity actionParameters(InputStream stream, EdmAction edmAction) throws DeserializerException;
+
+
+  /**
+   * Deserializes the Property or collections of properties (primitive & complex)
+   * @param stream
+   * @param edmProperty
+   * @return deserialized {@link Property}
+   * @throws DeserializerException
+   */
+  Property property(InputStream stream, EdmProperty edmProperty) throws DeserializerException;
+
+  /**
+   * Read entity references from the provided document
+   * @param stream
+   * @param keys
+   * @return
+   * @throws DeserializerException
+   */
+  List<URI> entityReferences(InputStream stream) throws DeserializerException;
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
index 14c588d..e5dd6b0 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
@@ -6,9 +6,9 @@
  * 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
@@ -30,6 +30,7 @@ public class EntityCollectionSerializerOptions {
   private CountOption count;
   private ExpandOption expand;
   private SelectOption select;
+  private boolean onlyReferences;
 
   /** Gets the {@link ContextURL}. */
   public ContextURL getContextURL() {
@@ -51,6 +52,11 @@ public class EntityCollectionSerializerOptions {
     return select;
   }
 
+  /** only writes the references of the entities*/
+  public boolean onlyReferences() {
+    return onlyReferences;
+  }
+
   /** Initializes the options builder. */
   public static Builder with() {
     return new Builder();
@@ -59,7 +65,7 @@ public class EntityCollectionSerializerOptions {
   /** Builder of OData serializer options. */
   public static final class Builder {
 
-    private EntityCollectionSerializerOptions options;
+    private final EntityCollectionSerializerOptions options;
 
     private Builder() {
       options = new EntityCollectionSerializerOptions();
@@ -89,6 +95,12 @@ public class EntityCollectionSerializerOptions {
       return this;
     }
 
+    /** Sets to serialize only references */
+    public Builder setWriteOnlyReferences(final boolean ref) {
+      options.onlyReferences = ref;
+      return this;
+    }
+
     /** Builds the OData serializer options. */
     public EntityCollectionSerializerOptions build() {
       return options;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
index fcbd150..0abb31c 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
@@ -6,9 +6,9 @@
  * 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
@@ -27,6 +27,7 @@ public class EntitySerializerOptions {
   private ContextURL contextURL;
   private ExpandOption expand;
   private SelectOption select;
+  private boolean onlyReferences;
 
   /** Gets the {@link ContextURL}. */
   public ContextURL getContextURL() {
@@ -43,6 +44,11 @@ public class EntitySerializerOptions {
     return select;
   }
 
+  /** only writes the references of the entities*/
+  public boolean onlyReferences() {
+    return onlyReferences;
+  }
+
   private EntitySerializerOptions() {}
 
   /** Initializes the options builder. */
@@ -53,7 +59,7 @@ public class EntitySerializerOptions {
   /** Builder of OData serializer options. */
   public static final class Builder {
 
-    private EntitySerializerOptions options;
+    private final EntitySerializerOptions options;
 
     private Builder() {
       options = new EntitySerializerOptions();
@@ -77,6 +83,12 @@ public class EntitySerializerOptions {
       return this;
     }
 
+    /** Sets to serialize only references */
+    public Builder setWriteOnlyReferences(final boolean ref) {
+      options.onlyReferences = ref;
+      return this;
+    }
+
     /** Builds the OData serializer options. */
     public EntitySerializerOptions build() {
       return options;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
index 72f8ee8..55377ce 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
@@ -6,9 +6,9 @@
  * 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
@@ -39,7 +39,7 @@ public interface ODataSerializer {
   /**
    * Writes the service document into an InputStream.
    * @param edm         the Entity Data Model
-   * @param serviceRoot the service-root URI of this OData service 
+   * @param serviceRoot the service-root URI of this OData service
    */
   InputStream serviceDocument(Edm edm, String serviceRoot) throws SerializerException;
 
@@ -58,21 +58,23 @@ public interface ODataSerializer {
 
   /**
    * Writes entity-collection data into an InputStream.
+   * @param metadata Metadata for the service
    * @param entityType the {@link EdmEntityType}
    * @param entitySet  the data of the entity set
    * @param options    options for the serializer
    */
-  InputStream entityCollection(EdmEntityType entityType, EntitySet entitySet,
-      EntityCollectionSerializerOptions options) throws SerializerException;
+  InputStream entityCollection(ServiceMetadata metadata, EdmEntityType entityType,
+      EntitySet entitySet, EntityCollectionSerializerOptions options) throws SerializerException;
 
   /**
    * Writes entity data into an InputStream.
+   * @param metadata Metadata for the service
    * @param entityType the {@link EdmEntityType}
    * @param entity     the data of the entity
    * @param options    options for the serializer
    */
-  InputStream entity(EdmEntityType entityType, Entity entity, EntitySerializerOptions options)
-      throws SerializerException;
+  InputStream entity(ServiceMetadata metadata, EdmEntityType entityType, Entity entity,
+      EntitySerializerOptions options) throws SerializerException;
 
   /**
    * Writes primitive-type instance data into an InputStream.
@@ -85,12 +87,13 @@ public interface ODataSerializer {
 
   /**
    * Writes complex-type instance data into an InputStream.
+   * @param metadata Metadata for the service
    * @param type     complex type
    * @param property property value
    * @param options options for the serializer
    */
-  InputStream complex(EdmComplexType type, Property property, ComplexSerializerOptions options)
-      throws SerializerException;
+  InputStream complex(ServiceMetadata metadata, EdmComplexType type, Property property,
+      ComplexSerializerOptions options) throws SerializerException;
 
   /**
    * Writes data of a collection of primitive-type instances into an InputStream.
@@ -103,10 +106,11 @@ public interface ODataSerializer {
 
   /**
    * Writes data of a collection of complex-type instances into an InputStream.
+   * @param metadata Metadata for the service
    * @param type     complex type
    * @param property property value
    * @param options options for the serializer
    */
-  InputStream complexCollection(EdmComplexType type, Property property, ComplexSerializerOptions options)
-      throws SerializerException;
+  InputStream complexCollection(ServiceMetadata metadata, EdmComplexType type, Property property,
+      ComplexSerializerOptions options) throws SerializerException;
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
index 1583241..a7d067f 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
@@ -6,9 +6,9 @@
  * 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
@@ -37,7 +37,9 @@ public class SerializerException extends ODataTranslatedException {
     /** parameter: property name */ INCONSISTENT_PROPERTY_TYPE,
     /** parameter: property name */ MISSING_PROPERTY,
     /** parameters: property name, property value */ WRONG_PROPERTY_VALUE,
-    /** parameters: primitive-type name, value */ WRONG_PRIMITIVE_VALUE;
+    /** parameters: primitive-type name, value */ WRONG_PRIMITIVE_VALUE,
+    UNKNOWN_TYPE,
+    WRONG_BASE_TYPE;
 
     @Override
     public String getKey() {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/pom.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/pom.xml b/lib/server-core-ext/pom.xml
new file mode 100644
index 0000000..a5730c0
--- /dev/null
+++ b/lib/server-core-ext/pom.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>odata-server-core-ext</artifactId>
+  <packaging>jar</packaging>
+  <name>${project.artifactId}</name>
+
+  <parent>
+    <groupId>org.apache.olingo</groupId>
+    <artifactId>odata-lib</artifactId>
+    <version>4.0.0-beta-03-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <properties>
+    <jetty-version>9.2.7.v20150116</jetty-version>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>odata-server-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>odata-server-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>odata-commons-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.antlr</groupId>
+      <artifactId>antlr4-runtime</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>javax.xml.stream</groupId>
+        <artifactId>stax-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <scope>test</scope>
+    </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <scope>test</scope>
+            <version>${jetty-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlet</artifactId>
+            <version>${jetty-version}</version>
+            <scope>test</scope>
+            <exclusions>
+              <exclusion>
+                <groupId>javax.servlet</groupId>
+                <artifactId>javax.servlet-api</artifactId>
+              </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-http</artifactId>
+            <version>${jetty-version}</version>
+            <scope>test</scope>
+        </dependency>    
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-client</artifactId>
+            <scope>test</scope>
+            <version>${jetty-version}</version>
+        </dependency>        
+  </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
new file mode 100644
index 0000000..199c62d
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core;
+
+import java.io.ByteArrayInputStream;
+
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+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.batch.exception.BatchDeserializerException;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+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.core.uri.parser.Parser;
+import org.apache.olingo.server.core.uri.parser.UriParserException;
+import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
+import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException;
+import org.apache.olingo.server.core.uri.validator.UriValidationException;
+
+public class ErrorHandler {
+  private final OData odata;
+  private final ServiceMetadata metadata;
+  private final CustomContentTypeSupport customContent;
+
+  public ErrorHandler(OData odata, ServiceMetadata metadata, CustomContentTypeSupport customContent) {
+    this.odata = odata;
+    this.metadata = metadata;
+    this.customContent = customContent;
+  }
+
+  public void handleException(Exception e, ODataRequest request, ODataResponse response) {
+    if (e instanceof UriValidationException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((UriValidationException)e, null);
+      handleServerError(request, response, serverError);
+    } else if(e instanceof UriParserSemanticException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((UriParserSemanticException)e, null);
+      handleServerError(request, response, serverError);
+    } else if(e instanceof  UriParserSyntaxException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((UriParserSyntaxException)e, null);
+      handleServerError(request, response, serverError);
+    } else if(e instanceof  UriParserException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((UriParserException)e, null);
+      handleServerError(request, response, serverError);
+    } else if(e instanceof ContentNegotiatorException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((ContentNegotiatorException)e, null);
+      handleServerError(request, response, serverError);
+    } else if(e instanceof SerializerException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((SerializerException)e, null);
+      handleServerError(request, response, serverError);
+    } else if(e instanceof BatchDeserializerException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((BatchDeserializerException)e, null);
+      handleServerError(request, response, serverError);
+    } else if(e instanceof DeserializerException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((DeserializerException)e, null);
+      handleServerError(request, response, serverError);
+    } else if(e instanceof ODataHandlerException) {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((ODataHandlerException)e, null);
+      handleServerError(request, response, serverError);
+    } else {
+      ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e);
+      handleServerError(request, response, serverError);
+    }
+  }
+
+  void handleServerError(final ODataRequest request, final ODataResponse response,
+      final ODataServerError serverError) {
+    ContentType requestedContentType;
+    try {
+      UriInfo uriInfo = new Parser().parseUri(request.getRawODataPath(), request.getRawQueryPath(),
+          null, this.metadata.getEdm());
+      requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+          request, this.customContent, RepresentationType.ERROR);
+    } catch (final ContentNegotiatorException e) {
+      requestedContentType = ODataFormat.JSON.getContentType();
+    } catch (UriParserException e) {
+      requestedContentType = ODataFormat.JSON.getContentType();
+    }
+    processError(response, serverError, requestedContentType);
+  }
+
+  void processError(ODataResponse response, ODataServerError serverError,
+      ContentType requestedContentType) {
+    try {
+      ODataSerializer serializer = this.odata.createSerializer(ODataFormat
+          .fromContentType(requestedContentType));
+      response.setContent(serializer.error(serverError));
+      response.setStatusCode(serverError.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+    } catch (Exception e) {
+      // This should never happen but to be sure we have this catch here
+      // to prevent sending a stacktrace to a client.
+      String responseContent = "{\"error\":{\"code\":null,\"message\":\"An unexpected exception occurred during "
+          + "error processing with message: " + e.getMessage() + "\"}}"; //$NON-NLS-1$ //$NON-NLS-2$
+      response.setContent(new ByteArrayInputStream(responseContent.getBytes()));
+      response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE,
+          ContentType.APPLICATION_JSON.toContentTypeString());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
new file mode 100644
index 0000000..e34a28a
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
@@ -0,0 +1,679 @@
+/*
+ * 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.core;
+
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.Action;
+import org.apache.olingo.commons.api.edm.provider.ActionImport;
+import org.apache.olingo.commons.api.edm.provider.ComplexType;
+import org.apache.olingo.commons.api.edm.provider.EdmProvider;
+import org.apache.olingo.commons.api.edm.provider.EntityContainer;
+import org.apache.olingo.commons.api.edm.provider.EntitySet;
+import org.apache.olingo.commons.api.edm.provider.EntityType;
+import org.apache.olingo.commons.api.edm.provider.EnumMember;
+import org.apache.olingo.commons.api.edm.provider.EnumType;
+import org.apache.olingo.commons.api.edm.provider.Function;
+import org.apache.olingo.commons.api.edm.provider.FunctionImport;
+import org.apache.olingo.commons.api.edm.provider.NavigationProperty;
+import org.apache.olingo.commons.api.edm.provider.NavigationPropertyBinding;
+import org.apache.olingo.commons.api.edm.provider.OnDelete;
+import org.apache.olingo.commons.api.edm.provider.OnDeleteAction;
+import org.apache.olingo.commons.api.edm.provider.Operation;
+import org.apache.olingo.commons.api.edm.provider.Parameter;
+import org.apache.olingo.commons.api.edm.provider.Property;
+import org.apache.olingo.commons.api.edm.provider.PropertyRef;
+import org.apache.olingo.commons.api.edm.provider.ReferentialConstraint;
+import org.apache.olingo.commons.api.edm.provider.ReturnType;
+import org.apache.olingo.commons.api.edm.provider.Schema;
+import org.apache.olingo.commons.api.edm.provider.Singleton;
+import org.apache.olingo.commons.api.edm.provider.Term;
+import org.apache.olingo.commons.api.edm.provider.TypeDefinition;
+
+/**
+ * This class can convert a CSDL document into EDMProvider object
+ */
+public class MetadataParser {
+
+  public EdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
+    XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+    XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
+
+    SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+    new ElementReader<SchemaBasedEdmProvider>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
+          String name) throws XMLStreamException {
+        String version = attr(element, "Version");
+        if (version.equals("4.0")) {
+          readDataServicesAndReference(reader, element, provider);
+        }
+      }
+    }.read(reader, null, provider, "Edmx");
+
+    return provider;
+  }
+
+  private void readDataServicesAndReference(XMLEventReader reader, StartElement element,
+      SchemaBasedEdmProvider provider) throws XMLStreamException {
+    new ElementReader<SchemaBasedEdmProvider>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
+          String name) throws XMLStreamException {
+        if (name.equals("DataServices")) {
+          readSchema(reader, element, provider);
+        } else if (name.equals("Reference")) {
+          readReference(reader, element, provider, "Reference");
+        }
+      }
+    }.read(reader, element, provider, "DataServices", "Reference");
+  }
+
+  private void readReference(XMLEventReader reader, StartElement element,
+      SchemaBasedEdmProvider provider, String name) throws XMLStreamException {
+    new ElementReader<SchemaBasedEdmProvider>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider t, String name)
+          throws XMLStreamException {
+        // TODO:
+      }
+    }.read(reader, element, provider, name);
+  }
+
+  private void readSchema(XMLEventReader reader, StartElement element,
+      SchemaBasedEdmProvider provider) throws XMLStreamException {
+
+    Schema schema = new Schema();
+    schema.setComplexTypes(new ArrayList<ComplexType>());
+    schema.setActions(new ArrayList<Action>());
+    schema.setEntityTypes(new ArrayList<EntityType>());
+    schema.setEnumTypes(new ArrayList<EnumType>());
+    schema.setFunctions(new ArrayList<Function>());
+    schema.setTerms(new ArrayList<Term>());
+    schema.setTypeDefinitions(new ArrayList<TypeDefinition>());
+
+    new ElementReader<Schema>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, Schema schema, String name)
+          throws XMLStreamException {
+        schema.setNamespace(attr(element, "Namespace"));
+        schema.setAlias(attr(element, "Alias"));
+        readSchemaContents(reader, schema);
+      }
+    }.read(reader, element, schema, "Schema");
+    provider.addSchema(schema);
+  }
+
+  private void readSchemaContents(XMLEventReader reader, Schema schema) throws XMLStreamException {
+    new ElementReader<Schema>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, Schema schema, String name)
+          throws XMLStreamException {
+        if (name.equals("Action")) {
+          readAction(reader, element, schema);
+        } else if (name.equals("Annotations")) {
+          // TODO:
+        } else if (name.equals("Annotation")) {
+          // TODO:
+        } else if (name.equals("ComplexType")) {
+          readComplexType(reader, element, schema);
+        } else if (name.equals("EntityContainer")) {
+          readEntityContainer(reader, element, schema);
+        } else if (name.equals("EntityType")) {
+          readEntityType(reader, element, schema);
+        } else if (name.equals("EnumType")) {
+          readEnumType(reader, element, schema);
+        } else if (name.equals("Function")) {
+          readFunction(reader, element, schema);
+        } else if (name.equals("Term")) {
+          schema.getTerms().add(readTerm(element));
+        } else if (name.equals("TypeDefinition")) {
+          schema.getTypeDefinitions().add(readTypeDefinition(element));
+        }
+      }
+    }.read(reader, null, schema, "Action", "Annotations", "Annotation", "ComplexType",
+        "EntityContainer", "EntityType", "EnumType", "Function", "Term", "TypeDefinition");
+  }
+
+  private void readAction(XMLEventReader reader, StartElement element, Schema schema)
+      throws XMLStreamException {
+
+    Action action = new Action();
+    action.setParameters(new ArrayList<Parameter>());
+    action.setName(attr(element, "Name"));
+    action.setBound(Boolean.parseBoolean(attr(element, "IsBound")));
+    String entitySetPath = attr(element, "EntitySetPath");
+    if (entitySetPath != null) {
+      // TODO: need to parse into binding and path.
+      action.setEntitySetPath(entitySetPath);
+    }
+    readOperationParameters(reader, action);
+    schema.getActions().add(action);
+  }
+
+  private FullQualifiedName readType(StartElement element) {
+    String type = attr(element, "Type");
+    if (type.startsWith("Collection(") && type.endsWith(")")) {
+      return new FullQualifiedName(type.substring(11, type.length() - 1));
+    }
+    return new FullQualifiedName(type);
+  }
+
+  private boolean isCollectionType(StartElement element) {
+    String type = attr(element, "Type");
+    if (type.startsWith("Collection(") && type.endsWith(")")) {
+      return true;
+    }
+    return false;
+  }
+
+  private void readReturnType(StartElement element, Operation operation) {
+    ReturnType returnType = new ReturnType();
+    returnType.setType(readType(element));
+    returnType.setCollection(isCollectionType(element));
+    returnType.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
+
+    String maxLength = attr(element, "MaxLength");
+    if (maxLength != null) {
+      returnType.setMaxLength(Integer.parseInt(maxLength));
+    }
+    String precision = attr(element, "Precision");
+    if (precision != null) {
+      returnType.setPrecision(Integer.parseInt(precision));
+    }
+    String scale = attr(element, "Scale");
+    if (scale != null) {
+      returnType.setScale(Integer.parseInt(scale));
+    }
+    String srid = attr(element, "SRID");
+    if (srid != null) {
+      // TODO: no olingo support yet.
+    }
+    operation.setReturnType(returnType);
+  }
+
+  private void readParameter(StartElement element, Operation operation) {
+    Parameter parameter = new Parameter();
+    parameter.setName(attr(element, "Name"));
+    parameter.setType(readType(element));
+    parameter.setCollection(isCollectionType(element));
+    parameter.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
+
+    String maxLength = attr(element, "MaxLength");
+    if (maxLength != null) {
+      parameter.setMaxLength(Integer.parseInt(maxLength));
+    }
+    String precision = attr(element, "Precision");
+    if (precision != null) {
+      parameter.setPrecision(Integer.parseInt(precision));
+    }
+    String scale = attr(element, "Scale");
+    if (scale != null) {
+      parameter.setScale(Integer.parseInt(scale));
+    }
+    String srid = attr(element, "SRID");
+    if (srid != null) {
+      // TODO: no olingo support yet.
+    }
+    operation.getParameters().add(parameter);
+  }
+
+  private TypeDefinition readTypeDefinition(StartElement element) {
+    TypeDefinition td = new TypeDefinition();
+    td.setName(attr(element, "Name"));
+    td.setUnderlyingType(new FullQualifiedName(attr(element, "UnderlyingType")));
+    td.setUnicode(Boolean.parseBoolean(attr(element, "Unicode")));
+
+    String maxLength = attr(element, "MaxLength");
+    if (maxLength != null) {
+      td.setMaxLength(Integer.parseInt(maxLength));
+    }
+    String precision = attr(element, "Precision");
+    if (precision != null) {
+      td.setPrecision(Integer.parseInt(precision));
+    }
+    String scale = attr(element, "Scale");
+    if (scale != null) {
+      td.setScale(Integer.parseInt(scale));
+    }
+    String srid = attr(element, "SRID");
+    if (srid != null) {
+      // TODO: no olingo support yet.
+    }
+    return td;
+  }
+
+  private Term readTerm(StartElement element) {
+    Term term = new Term();
+    term.setName(attr(element, "Name"));
+    term.setType(attr(element, "Type"));
+    if (attr(element, "BaseTerm") != null) {
+      term.setBaseTerm(attr(element, "BaseTerm"));
+    }
+    if (attr(element, "DefaultValue") != null) {
+      term.setDefaultValue(attr(element, "DefaultValue"));
+    }
+    if (attr(element, "AppliesTo") != null) {
+      term.setAppliesTo(Arrays.asList(attr(element, "AppliesTo")));
+    }
+    term.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
+    String maxLength = attr(element, "MaxLength");
+    if (maxLength != null) {
+      term.setMaxLength(Integer.parseInt(maxLength));
+    }
+    String precision = attr(element, "Precision");
+    if (precision != null) {
+      term.setPrecision(Integer.parseInt(precision));
+    }
+    String scale = attr(element, "Scale");
+    if (scale != null) {
+      term.setScale(Integer.parseInt(scale));
+    }
+    String srid = attr(element, "SRID");
+    if (srid != null) {
+      // TODO: no olingo support yet.
+    }
+    return term;
+  }
+
+  private void readFunction(XMLEventReader reader, StartElement element, Schema schema)
+      throws XMLStreamException {
+    Function function = new Function();
+    function.setParameters(new ArrayList<Parameter>());
+    function.setName(attr(element, "Name"));
+    function.setBound(Boolean.parseBoolean(attr(element, "IsBound")));
+    function.setComposable(Boolean.parseBoolean(attr(element, "IsComposable")));
+    String entitySetPath = attr(element, "EntitySetPath");
+    if (entitySetPath != null) {
+      // TODO: need to parse into binding and path.
+      function.setEntitySetPath(entitySetPath);
+    }
+    readOperationParameters(reader, function);
+    schema.getFunctions().add(function);
+  }
+
+  private void readOperationParameters(XMLEventReader reader, final Operation operation)
+      throws XMLStreamException {
+    new ElementReader<Operation>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, Operation operation, String name)
+          throws XMLStreamException {
+        if (name.equals("Parameter")) {
+          readParameter(element, operation);
+        } else if (name.equals("ReturnType")) {
+          readReturnType(element, operation);
+        }
+      }
+    }.read(reader, null, operation, "Parameter", "ReturnType");
+  }
+
+  private void readEnumType(XMLEventReader reader, StartElement element, Schema schema)
+      throws XMLStreamException {
+    EnumType type = new EnumType();
+    type.setMembers(new ArrayList<EnumMember>());
+    type.setName(attr(element, "Name"));
+    if (attr(element, "UnderlyingType") != null) {
+      type.setUnderlyingType(new FullQualifiedName(attr(element, "UnderlyingType")));
+    }
+    type.setFlags(Boolean.parseBoolean(attr(element, "IsFlags")));
+
+    readEnumMembers(reader, element, type);
+    schema.getEnumTypes().add(type);
+  }
+
+  private void readEnumMembers(XMLEventReader reader, StartElement element, EnumType type)
+      throws XMLStreamException {
+    new ElementReader<EnumType>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, EnumType type, String name)
+          throws XMLStreamException {
+        EnumMember member = new EnumMember();
+        member.setName(attr(element, "Name"));
+        member.setValue(attr(element, "Value"));
+        type.getMembers().add(member);
+      }
+    }.read(reader, element, type, "Member");
+  }
+
+  private void readEntityType(XMLEventReader reader, StartElement element, Schema schema)
+      throws XMLStreamException {
+    EntityType entityType = new EntityType();
+    entityType.setProperties(new ArrayList<Property>());
+    entityType.setNavigationProperties(new ArrayList<NavigationProperty>());
+    entityType.setKey(new ArrayList<PropertyRef>());
+    entityType.setName(attr(element, "Name"));
+    if (attr(element, "BaseType") != null) {
+      entityType.setBaseType(new FullQualifiedName(attr(element, "BaseType")));
+    }
+    entityType.setAbstract(Boolean.parseBoolean(attr(element, "Abstract")));
+    entityType.setOpenType(Boolean.parseBoolean(attr(element, "OpenType")));
+    entityType.setHasStream(Boolean.parseBoolean(attr(element, "HasStream")));
+    readEntityProperties(reader, entityType);
+    schema.getEntityTypes().add(entityType);
+  }
+
+  private void readEntityProperties(XMLEventReader reader, EntityType entityType)
+      throws XMLStreamException {
+    new ElementReader<EntityType>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, EntityType entityType, String name)
+          throws XMLStreamException {
+        if (name.equals("Property")) {
+          entityType.getProperties().add(readProperty(element));
+        } else if (name.equals("NavigationProperty")) {
+          entityType.getNavigationProperties().add(readNavigationProperty(reader, element));
+        } else if (name.equals("Key")) {
+          readKey(reader, element, entityType);
+        }
+      }
+    }.read(reader, null, entityType, "Property", "NavigationProperty", "Key");
+  }
+
+  private void readKey(XMLEventReader reader, StartElement element, EntityType entityType)
+      throws XMLStreamException {
+    new ElementReader<EntityType>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, EntityType entityType, String name)
+          throws XMLStreamException {
+        PropertyRef ref = new PropertyRef();
+        ref.setName(attr(element, "Name"));
+        ref.setAlias(attr(element, "Alias"));
+        entityType.getKey().add(ref);
+      }
+    }.read(reader, element, entityType, "PropertyRef");
+  }
+
+  private NavigationProperty readNavigationProperty(XMLEventReader reader, StartElement element)
+      throws XMLStreamException {
+    NavigationProperty property = new NavigationProperty();
+    property.setReferentialConstraints(new ArrayList<ReferentialConstraint>());
+
+    property.setName(attr(element, "Name"));
+    property.setType(readType(element));
+    property.setCollection(isCollectionType(element));
+    property.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
+    property.setPartner(attr(element, "Partner"));
+    property.setContainsTarget(Boolean.parseBoolean(attr(element, "ContainsTarget")));
+
+    new ElementReader<NavigationProperty>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, NavigationProperty property,
+          String name) throws XMLStreamException {
+        if (name.equals("ReferentialConstraint")) {
+          ReferentialConstraint constraint = new ReferentialConstraint();
+          constraint.setProperty(attr(element, "Property"));
+          constraint.setReferencedProperty(attr(element, "ReferencedProperty"));
+          property.getReferentialConstraints().add(constraint);
+        } else if (name.equals("OnDelete")) {
+          property.setOnDelete(new OnDelete().setAction(OnDeleteAction.valueOf(attr(element, "Action"))));
+        }
+      }
+    }.read(reader, element, property, "ReferentialConstraint", "OnDelete");
+    return property;
+  }
+
+  private String attr(StartElement element, String name) {
+    Attribute attr = element.getAttributeByName(new QName(name));
+    if (attr != null) {
+      return attr.getValue();
+    }
+    return null;
+  }
+
+  private Property readProperty(StartElement element) {
+    Property property = new Property();
+    property.setName(attr(element, "Name"));
+    property.setType(readType(element));
+    property.setCollection(isCollectionType(element));
+    property.setNullable(Boolean.parseBoolean(attr(element, "Nullable") == null ? "true" : attr(
+        element, "Nullable")));
+    property.setUnicode(Boolean.parseBoolean(attr(element, "Unicode")));
+
+    String maxLength = attr(element, "MaxLength");
+    if (maxLength != null) {
+      property.setMaxLength(Integer.parseInt(maxLength));
+    }
+    String precision = attr(element, "Precision");
+    if (precision != null) {
+      property.setPrecision(Integer.parseInt(precision));
+    }
+    String scale = attr(element, "Scale");
+    if (scale != null) {
+      property.setScale(Integer.parseInt(scale));
+    }
+    String srid = attr(element, "SRID");
+    if (srid != null) {
+      // TODO: no olingo support yet.
+    }
+    String defaultValue = attr(element, "DefaultValue");
+    if (defaultValue != null) {
+      property.setDefaultValue(defaultValue);
+    }
+    return property;
+  }
+
+  private void readEntityContainer(XMLEventReader reader, StartElement element, Schema schema)
+      throws XMLStreamException {
+    final EntityContainer container = new EntityContainer();
+    container.setName(attr(element, "Name"));
+    if (attr(element, "Extends") != null) {
+      container.setExtendsContainer(attr(element, "Extends"));
+    }
+    container.setActionImports(new ArrayList<ActionImport>());
+    container.setFunctionImports(new ArrayList<FunctionImport>());
+    container.setEntitySets(new ArrayList<EntitySet>());
+    container.setSingletons(new ArrayList<Singleton>());
+
+    new ElementReader<Schema>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, Schema schema, String name)
+          throws XMLStreamException {
+        if (name.equals("EntitySet")) {
+          readEntitySet(reader, element, container);
+        } else if (name.equals("Singleton")) {
+          readSingleton(reader, element, container);
+        } else if (name.equals("ActionImport")) {
+          readActionImport(element, container);
+        } else if (name.equals("FunctionImport")) {
+          readFunctionImport(element, container);
+        }
+      }
+
+      private void readFunctionImport(StartElement element, EntityContainer container) {
+        FunctionImport functionImport = new FunctionImport();
+        functionImport.setName(attr(element, "Name"));
+        functionImport.setFunction(new FullQualifiedName(attr(element, "Function")));
+        functionImport.setIncludeInServiceDocument(Boolean.parseBoolean(attr(element,
+            "IncludeInServiceDocument")));
+
+        String entitySet = attr(element, "EntitySet");
+        if (entitySet != null) {
+          functionImport.setEntitySet(entitySet);
+        }
+        container.getFunctionImports().add(functionImport);
+      }
+
+      private void readActionImport(StartElement element, EntityContainer container) {
+        ActionImport actionImport = new ActionImport();
+        actionImport.setName(attr(element, "Name"));
+        actionImport.setAction(new FullQualifiedName(attr(element, "Action")));
+
+        String entitySet = attr(element, "EntitySet");
+        if (entitySet != null) {
+          actionImport.setEntitySet(entitySet);
+        }
+        container.getActionImports().add(actionImport);
+      }
+
+      private void readSingleton(XMLEventReader reader, StartElement element,
+          EntityContainer container) throws XMLStreamException {
+        Singleton singleton = new Singleton();
+        singleton.setNavigationPropertyBindings(new ArrayList<NavigationPropertyBinding>());
+        singleton.setName(attr(element, "Name"));
+        singleton.setType(new FullQualifiedName(attr(element, "Type")));
+        singleton.setNavigationPropertyBindings(new ArrayList<NavigationPropertyBinding>());
+        readNavigationPropertyBindings(reader, element, singleton.getNavigationPropertyBindings());
+        container.getSingletons().add(singleton);
+      }
+
+      private void readEntitySet(XMLEventReader reader, StartElement element,
+          EntityContainer container) throws XMLStreamException {
+        EntitySet entitySet = new EntitySet();
+        entitySet.setName(attr(element, "Name"));
+        entitySet.setType(new FullQualifiedName(attr(element, "EntityType")));
+        entitySet.setIncludeInServiceDocument(Boolean.parseBoolean(attr(element,
+            "IncludeInServiceDocument")));
+        entitySet.setNavigationPropertyBindings(new ArrayList<NavigationPropertyBinding>());
+        readNavigationPropertyBindings(reader, element, entitySet.getNavigationPropertyBindings());
+        container.getEntitySets().add(entitySet);
+      }
+
+      private void readNavigationPropertyBindings(XMLEventReader reader, StartElement element,
+          List<NavigationPropertyBinding> bindings) throws XMLStreamException {
+        new ElementReader<List<NavigationPropertyBinding>>() {
+          @Override
+          void build(XMLEventReader reader, StartElement element,
+              List<NavigationPropertyBinding> bindings, String name) throws XMLStreamException {
+            NavigationPropertyBinding binding = new NavigationPropertyBinding();
+            binding.setPath(attr(element, "Path"));
+            binding.setTarget(attr(element, "Target"));
+            bindings.add(binding);
+          }
+
+        }.read(reader, element, bindings, "NavigationPropertyBinding");
+        ;
+      }
+    }.read(reader, element, schema, "EntitySet", "Singleton", "ActionImport", "FunctionImport");
+    schema.setEntityContainer(container);
+  }
+
+  private void readComplexType(XMLEventReader reader, StartElement element, Schema schema)
+      throws XMLStreamException {
+    ComplexType complexType = new ComplexType();
+    complexType.setProperties(new ArrayList<Property>());
+    complexType.setNavigationProperties(new ArrayList<NavigationProperty>());
+    complexType.setName(attr(element, "Name"));
+    if (attr(element, "BaseType") != null) {
+      complexType.setBaseType(new FullQualifiedName(attr(element, "BaseType")));
+    }
+    complexType.setAbstract(Boolean.parseBoolean(attr(element, "Abstract")));
+    complexType.setOpenType(Boolean.parseBoolean(attr(element, "OpenType")));
+    readProperties(reader, complexType);
+
+    schema.getComplexTypes().add(complexType);
+  }
+
+  private void readProperties(XMLEventReader reader, ComplexType complexType)
+      throws XMLStreamException {
+    new ElementReader<ComplexType>() {
+      @Override
+      void build(XMLEventReader reader, StartElement element, ComplexType complexType, String name)
+          throws XMLStreamException {
+        if (name.equals("Property")) {
+          complexType.getProperties().add(readProperty(element));
+        } else if (name.equals("NavigationProperty")) {
+          complexType.getNavigationProperties().add(readNavigationProperty(reader, element));
+        }
+      }
+    }.read(reader, null, complexType, "Property", "NavigationProperty");
+  }
+
+  abstract class ElementReader<T> {
+    void read(XMLEventReader reader, StartElement element, T t, String... names)
+        throws XMLStreamException {
+      while (reader.hasNext()) {
+        XMLEvent event = reader.peek();
+
+        event = skipAnnotations(reader, event);
+
+        if (!event.isStartElement() && !event.isEndElement()) {
+          reader.nextEvent();
+          continue;
+        }
+
+        boolean hit = false;
+
+        for (int i = 0; i < names.length; i++) {
+          if (event.isStartElement()) {
+            element = event.asStartElement();
+            if (element.getName().getLocalPart().equals(names[i])) {
+              reader.nextEvent(); // advance cursor
+              // System.out.println("reading = "+names[i]);
+              build(reader, element, t, names[i]);
+              hit = true;
+            }
+          }
+          if (event.isEndElement()) {
+            EndElement e = event.asEndElement();
+            if (e.getName().getLocalPart().equals(names[i])) {
+              reader.nextEvent(); // advance cursor
+              // System.out.println("done reading = "+names[i]);
+              hit = true;
+            }
+          }
+        }
+        if (!hit) {
+          break;
+        }
+      }
+    }
+
+    private XMLEvent skipAnnotations(XMLEventReader reader, XMLEvent event)
+        throws XMLStreamException {
+      boolean skip = false;
+
+      while (reader.hasNext()) {
+        if (event.isStartElement()) {
+          StartElement element = event.asStartElement();
+          if (element.getName().getLocalPart().equals("Annotation")) {
+            skip = true;
+          }
+        }
+        if (event.isEndElement()) {
+          EndElement element = event.asEndElement();
+          if (element.getName().getLocalPart().equals("Annotation")) {
+            return reader.peek();
+          }
+        }
+        if (skip) {
+          event = reader.nextEvent();
+        } else {
+          return event;
+        }
+      }
+      return event;
+    }
+
+    abstract void build(XMLEventReader reader, StartElement element, T t, String name)
+        throws XMLStreamException;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
new file mode 100644
index 0000000..ddb8e6b
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
@@ -0,0 +1,123 @@
+/*
+ * 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.core;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ODataTranslatedException;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.processor.Processor;
+import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.legacy.ProcessorServiceHandler;
+
+public class OData4HttpHandler extends ODataHttpHandlerImpl {
+  private ServiceHandler handler;
+  private final ServiceMetadata serviceMetadata;
+  private final OData odata;
+  private CustomContentTypeSupport customContentTypeSupport;
+
+
+  public OData4HttpHandler(OData odata, ServiceMetadata serviceMetadata) {
+    super(odata, serviceMetadata);
+    this.odata = odata;
+    this.serviceMetadata = serviceMetadata;
+    // this is support old interfaces
+    this.handler = new ProcessorServiceHandler();
+    this.handler.init(odata, serviceMetadata);
+  }
+
+  @Override
+  public void process(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse) {
+    ODataRequest request = null;
+    ODataResponse response = new ODataResponse();
+
+    try {
+      request = createODataRequest(httpRequest, 0);
+      validateODataVersion(request, response);
+
+      ServiceDispatcher dispatcher = new ServiceDispatcher(this.odata, this.serviceMetadata,
+          handler, this.customContentTypeSupport);
+      dispatcher.execute(request, response);
+
+    } catch (Exception e) {
+      ErrorHandler handler = new ErrorHandler(this.odata, this.serviceMetadata,
+          this.customContentTypeSupport);
+      handler.handleException(e, request, response);
+    }
+    convertToHttp(httpResponse, response);
+  }
+
+
+  ODataRequest createODataRequest(final HttpServletRequest httpRequest, final int split)
+      throws ODataTranslatedException {
+    try {
+      ODataRequest odRequest = new ODataRequest();
+
+      odRequest.setBody(httpRequest.getInputStream());
+      extractHeaders(odRequest, httpRequest);
+      extractMethod(odRequest, httpRequest);
+      extractUri(odRequest, httpRequest, split);
+
+      return odRequest;
+    } catch (final IOException e) {
+      throw new SerializerException(
+          "An I/O exception occurred.", e, SerializerException.MessageKeys.IO_EXCEPTION); //$NON-NLS-1$
+    }
+  }
+
+  void validateODataVersion(final ODataRequest request, final ODataResponse response)
+      throws ODataHandlerException {
+    final String maxVersion = request.getHeader(HttpHeader.ODATA_MAX_VERSION);
+    response.setHeader(HttpHeader.ODATA_VERSION, ODataServiceVersion.V40.toString());
+
+    if (maxVersion != null) {
+      if (ODataServiceVersion.isBiggerThan(ODataServiceVersion.V40.toString(), maxVersion)) {
+        throw new ODataHandlerException("ODataVersion not supported: " + maxVersion, //$NON-NLS-1$
+            ODataHandlerException.MessageKeys.ODATA_VERSION_NOT_SUPPORTED, maxVersion);
+      }
+    }
+  }
+
+  @Override
+  public void register(final Processor processor) {
+
+    if (processor instanceof ServiceHandler) {
+      this.handler = (ServiceHandler) processor;
+      this.handler.init(this.odata, this.serviceMetadata);
+    }
+
+    if (this.handler instanceof ProcessorServiceHandler) {
+      ((ProcessorServiceHandler)this.handler).register(processor);
+    }
+  }
+
+  @Override
+  public void register(final CustomContentTypeSupport customContentTypeSupport) {
+    this.customContentTypeSupport = customContentTypeSupport;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4Impl.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4Impl.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4Impl.java
new file mode 100644
index 0000000..bde9c96
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4Impl.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.core;
+
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataHttpHandler;
+import org.apache.olingo.server.api.ServiceMetadata;
+
+public class OData4Impl extends ODataImpl {
+
+  public static OData newInstance() {
+    try {
+      final Class<?> clazz = Class.forName(OData4Impl.class.getName());
+      final Object object = clazz.newInstance();
+      return (OData) object;
+    } catch (final Exception e) {
+      throw new ODataRuntimeException(e);
+    }
+  }
+
+  private OData4Impl() {
+  }
+
+  @Override
+  public ODataHttpHandler createHandler(final ServiceMetadata edm) {
+    return new OData4HttpHandler(this, edm);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/RequestURLHierarchyVisitor.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/RequestURLHierarchyVisitor.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/RequestURLHierarchyVisitor.java
new file mode 100644
index 0000000..ee00638
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/RequestURLHierarchyVisitor.java
@@ -0,0 +1,333 @@
+/*
+ * 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.core;
+
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriInfoAll;
+import org.apache.olingo.server.api.uri.UriInfoBatch;
+import org.apache.olingo.server.api.uri.UriInfoCrossjoin;
+import org.apache.olingo.server.api.uri.UriInfoEntityId;
+import org.apache.olingo.server.api.uri.UriInfoKind;
+import org.apache.olingo.server.api.uri.UriInfoMetadata;
+import org.apache.olingo.server.api.uri.UriInfoResource;
+import org.apache.olingo.server.api.uri.UriInfoService;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceAction;
+import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
+import org.apache.olingo.server.api.uri.UriResourceCount;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceFunction;
+import org.apache.olingo.server.api.uri.UriResourceIt;
+import org.apache.olingo.server.api.uri.UriResourceLambdaAll;
+import org.apache.olingo.server.api.uri.UriResourceLambdaAny;
+import org.apache.olingo.server.api.uri.UriResourceLambdaVariable;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
+import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
+import org.apache.olingo.server.api.uri.UriResourceRef;
+import org.apache.olingo.server.api.uri.UriResourceRoot;
+import org.apache.olingo.server.api.uri.UriResourceSingleton;
+import org.apache.olingo.server.api.uri.UriResourceValue;
+import org.apache.olingo.server.api.uri.queryoption.CountOption;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.FilterOption;
+import org.apache.olingo.server.api.uri.queryoption.FormatOption;
+import org.apache.olingo.server.api.uri.queryoption.IdOption;
+import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
+import org.apache.olingo.server.api.uri.queryoption.SearchOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+import org.apache.olingo.server.api.uri.queryoption.SkipOption;
+import org.apache.olingo.server.api.uri.queryoption.SkipTokenOption;
+import org.apache.olingo.server.api.uri.queryoption.TopOption;
+
+public class RequestURLHierarchyVisitor implements RequestURLVisitor {
+
+  private UriInfo uriInfo;
+
+  public UriInfo getUriInfo() {
+    return this.uriInfo;
+  }
+
+  @Override
+  public void visit(UriInfo info) {
+    this.uriInfo = info;
+
+    UriInfoKind kind = info.getKind();
+    switch (kind) {
+    case all:
+      visit(info.asUriInfoAll());
+      break;
+    case batch:
+      visit(info.asUriInfoBatch());
+      break;
+    case crossjoin:
+      visit(info.asUriInfoCrossjoin());
+      break;
+    case entityId:
+      visit(info.asUriInfoEntityId());
+      break;
+    case metadata:
+      visit(info.asUriInfoMetadata());
+      break;
+    case resource:
+      visit(info.asUriInfoResource());
+      break;
+    case service:
+      visit(info.asUriInfoService());
+      break;
+    }
+  }
+
+  @Override
+  public void visit(UriInfoService info) {
+  }
+
+  @Override
+  public void visit(UriInfoAll info) {
+  }
+
+  @Override
+  public void visit(UriInfoBatch info) {
+  }
+
+  @Override
+  public void visit(UriInfoCrossjoin info) {
+  }
+
+  @Override
+  public void visit(UriInfoEntityId info) {
+    visit(info.getSelectOption());
+
+    if (info.getExpandOption() != null) {
+      visit(info.getExpandOption());
+    }
+    if (info.getFormatOption() != null) {
+      visit(info.getFormatOption());
+    }
+    if (info.getIdOption() != null) {
+      visit(info.getIdOption(), info.getEntityTypeCast());
+    }
+  }
+
+  @Override
+  public void visit(UriInfoMetadata info) {
+  }
+
+  @Override
+  public void visit(UriInfoResource info) {
+    List<UriResource> parts = info.getUriResourceParts();
+    for (UriResource resource : parts) {
+      switch (resource.getKind()) {
+      case action:
+        visit((UriResourceAction) resource);
+        break;
+      case complexProperty:
+        visit((UriResourceComplexProperty) resource);
+        break;
+      case count:
+        visit((UriResourceCount) resource);
+        break;
+      case entitySet:
+        visit((UriResourceEntitySet) resource);
+        break;
+      case function:
+        visit((UriResourceFunction) resource);
+        break;
+      case it:
+        visit((UriResourceIt) resource);
+        break;
+      case lambdaAll:
+        visit((UriResourceLambdaAll) resource);
+        break;
+      case lambdaAny:
+        visit((UriResourceLambdaAny) resource);
+        break;
+      case lambdaVariable:
+        visit((UriResourceLambdaVariable) resource);
+        break;
+      case navigationProperty:
+        visit((UriResourceNavigation) resource);
+        break;
+      case ref:
+        visit((UriResourceRef) resource);
+        break;
+      case root:
+        visit((UriResourceRoot) resource);
+        break;
+      case primitiveProperty:
+        visit((UriResourcePrimitiveProperty) resource);
+        break;
+      case singleton:
+        visit((UriResourceSingleton) resource);
+        break;
+      case value:
+        visit((UriResourceValue) resource);
+        break;
+      }
+    }
+
+    // http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793682
+    if (info.getSearchOption() != null) {
+      visit(info.getSearchOption());
+    }
+
+    if (info.getFilterOption() != null) {
+      visit(info.getFilterOption());
+    }
+
+    if (info.getCountOption() != null) {
+      visit(info.getCountOption());
+    }
+
+    visit(info.getOrderByOption());
+
+    if (info.getSkipOption() != null) {
+      visit(info.getSkipOption());
+    }
+
+    if (info.getTopOption() != null) {
+      visit(info.getTopOption());
+    }
+
+    if (info.getExpandOption() != null) {
+      visit(info.getExpandOption());
+    }
+
+    visit(info.getSelectOption());
+
+    if (info.getFormatOption() != null) {
+      visit(info.getFormatOption());
+    }
+
+    if (info.getIdOption() != null) {
+      visit(info.getIdOption(), null);
+    }
+
+    if (info.getSkipTokenOption() != null) {
+      visit(info.getSkipTokenOption());
+    }
+
+  }
+
+  @Override
+  public void visit(ExpandOption option) {
+  }
+
+  @Override
+  public void visit(FilterOption info) {
+  }
+
+  @Override
+  public void visit(FormatOption info) {
+  }
+
+  @Override
+  public void visit(IdOption info, EdmEntityType type) {
+  }
+
+  @Override
+  public void visit(CountOption info) {
+  }
+
+  @Override
+  public void visit(OrderByOption option) {
+  }
+
+  @Override
+  public void visit(SearchOption option) {
+  }
+
+  @Override
+  public void visit(SelectOption option) {
+  }
+
+  @Override
+  public void visit(SkipOption option) {
+  }
+
+  @Override
+  public void visit(SkipTokenOption option) {
+  }
+
+  @Override
+  public void visit(TopOption option) {
+  }
+
+  @Override
+  public void visit(UriResourceCount option) {
+  }
+
+  @Override
+  public void visit(UriResourceRef info) {
+  }
+
+  @Override
+  public void visit(UriResourceRoot info) {
+  }
+
+  @Override
+  public void visit(UriResourceValue info) {
+  }
+
+  @Override
+  public void visit(UriResourceAction info) {
+  }
+
+  @Override
+  public void visit(UriResourceEntitySet info) {
+  }
+
+  @Override
+  public void visit(UriResourceFunction info) {
+  }
+
+  @Override
+  public void visit(UriResourceIt info) {
+  }
+
+  @Override
+  public void visit(UriResourceLambdaAll info) {
+  }
+
+  @Override
+  public void visit(UriResourceLambdaAny info) {
+  }
+
+  @Override
+  public void visit(UriResourceLambdaVariable info) {
+  }
+
+  @Override
+  public void visit(UriResourceNavigation info) {
+  }
+
+  @Override
+  public void visit(UriResourceSingleton info) {
+  }
+
+  @Override
+  public void visit(UriResourceComplexProperty info) {
+  }
+
+  @Override
+  public void visit(UriResourcePrimitiveProperty info) {
+  }
+}