You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/07/23 10:58:26 UTC

[1/2] [OLINGO-317] Split ContextURL in parser and builder

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 5476bad19 -> c75c29ce0


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
new file mode 100644
index 0000000..faeb571
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
@@ -0,0 +1,57 @@
+/*
+ * 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.serializer.utils;
+
+import java.net.URI;
+
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.core.Encoder;
+
+public final class ContextURLBuilder {
+
+  public static final URI create(final ContextURL contextURL) {
+    StringBuilder result = new StringBuilder();
+    if (contextURL.getServiceRoot() != null) {
+      result.append(contextURL.getServiceRoot());
+    }
+    result.append(Constants.METADATA);
+    if (contextURL.getEntitySetOrSingletonOrType() != null) {
+      result.append('#').append(Encoder.encode(contextURL.getEntitySetOrSingletonOrType()));
+    }
+    if (contextURL.getDerivedEntity() != null) {
+      if (contextURL.getEntitySetOrSingletonOrType() == null) {
+        throw new IllegalArgumentException("ContextURL: Derived Type without anything to derive from!");
+      }
+      result.append('/').append(Encoder.encode(contextURL.getDerivedEntity()));
+    }
+    if (contextURL.isReference()) {
+      if (contextURL.getEntitySetOrSingletonOrType() != null) {
+        throw new IllegalArgumentException("ContextURL: $ref with Entity Set");
+      }
+      result.append('#').append(ContextURL.Suffix.REFERENCE.getRepresentation());
+    } else if (contextURL.getSuffix() != null) {
+      if (contextURL.getEntitySetOrSingletonOrType() == null) {
+        throw new IllegalArgumentException("ContextURL: Suffix without preceding Entity Set!");
+      }
+      result.append('/').append(contextURL.getSuffix().getRepresentation());
+    }
+    return URI.create(result.toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java
new file mode 100644
index 0000000..6993d3b
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.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.serializer.utils;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.URI;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.ContextURL.Suffix;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class ContextURLBuilderTest {
+
+  @Test
+  public void buildServiceDocument() {
+    ContextURL contextURL = ContextURL.Builder.create()
+        .serviceRoot(URI.create("http://host/service/")).build();
+    assertEquals("http://host/service/$metadata", ContextURLBuilder.create(contextURL).toASCIIString());
+  }
+
+  @Test
+  public void buildRelative() {
+    ContextURL contextURL = ContextURL.Builder.create().build();
+    assertEquals("$metadata", ContextURLBuilder.create(contextURL).toASCIIString());
+  }
+
+  @Test
+  public void buildEntitySet() {
+    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
+    Mockito.when(entitySet.getName()).thenReturn("Customers");
+    ContextURL contextURL = ContextURL.Builder.create().serviceRoot(URI.create("http://host/service/"))
+        .entitySet(entitySet)
+        .build();
+    assertEquals("http://host/service/$metadata#Customers", ContextURLBuilder.create(contextURL).toASCIIString());
+  }
+
+  @Test
+  public void buildDerivedEntitySet() {
+    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
+    Mockito.when(entitySet.getName()).thenReturn("Customers");
+    EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
+    Mockito.when(derivedType.getFullQualifiedName()).thenReturn(new FullQualifiedName("Model", "VipCustomer"));
+    ContextURL contextURL = ContextURL.Builder.create().serviceRoot(URI.create("http://host/service/"))
+        .entitySet(entitySet)
+        .derived(derivedType)
+        .build();
+    assertEquals("http://host/service/$metadata#Customers/Model.VipCustomer",
+        ContextURLBuilder.create(contextURL).toASCIIString());
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void buildDerivedEntitySetWithoutEntitySet() {
+    EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
+    Mockito.when(derivedType.getFullQualifiedName()).thenReturn(new FullQualifiedName("Model", "VipCustomer"));
+    ContextURLBuilder.create(ContextURL.Builder.create().derived(derivedType).build());
+  }
+
+  @Test
+  public void buildDerivedEntity() {
+    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
+    Mockito.when(entitySet.getName()).thenReturn("Customers");
+    EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
+    Mockito.when(derivedType.getFullQualifiedName()).thenReturn(new FullQualifiedName("Model", "VipCustomer"));
+    ContextURL contextURL = ContextURL.Builder.create().serviceRoot(URI.create("http://host/service/"))
+        .entitySet(entitySet)
+        .derived(derivedType)
+        .suffix(Suffix.ENTITY)
+        .build();
+    assertEquals("http://host/service/$metadata#Customers/Model.VipCustomer/$entity",
+        ContextURLBuilder.create(contextURL).toASCIIString());
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void buildSuffixWithoutEntitySet() {
+    ContextURLBuilder.create(ContextURL.Builder.create().suffix(Suffix.ENTITY).build());
+  }
+
+  @Test
+  public void buildReference() {
+    ContextURL contextURL = ContextURL.Builder.create().suffix(Suffix.REFERENCE).build();
+    assertEquals("$metadata#$ref", ContextURLBuilder.create(contextURL).toASCIIString());
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void buildReferenceWithEntitySet() {
+    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
+    Mockito.when(entitySet.getName()).thenReturn("Customers");
+    ContextURLBuilder.create(ContextURL.Builder.create().entitySet(entitySet).suffix(Suffix.REFERENCE).build());
+  }
+
+  @Test
+  public void buildWithCharactersToBeEscaped() {
+    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
+    Mockito.when(entitySet.getName()).thenReturn("Entitäten");
+    EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
+    Mockito.when(derivedType.getFullQualifiedName()).thenReturn(
+        new FullQualifiedName("Namensräumchen", "UnüblicherName"));
+    ContextURL contextURL = ContextURL.Builder.create().entitySet(entitySet).derived(derivedType).build();
+    assertEquals("$metadata#Entit%C3%A4ten/Namensr%C3%A4umchen.Un%C3%BCblicherName",
+        ContextURLBuilder.create(contextURL).toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/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 7dfba98..03434d9 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
@@ -27,6 +27,7 @@ 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.api.serialization.ODataSerializerException;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
@@ -78,6 +79,8 @@ public class TechnicalProcessor implements CollectionProcessor, EntityProcessor
       }
     } catch (final DataProvider.DataProviderException e) {
       response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+    } catch (final ODataSerializerException e) {
+      response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
     }
   }
 
@@ -101,6 +104,8 @@ public class TechnicalProcessor implements CollectionProcessor, EntityProcessor
       }
     } catch (final DataProvider.DataProviderException e) {
       response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+    } catch (final ODataSerializerException e) {
+      response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
     }
   }
 
@@ -147,6 +152,6 @@ public class TechnicalProcessor implements CollectionProcessor, EntityProcessor
   }
 
   private ContextURL getContextUrl(final EdmEntitySet entitySet) {
-    return ContextURL.create().entitySet(entitySet).build();
+    return ContextURL.Builder.create().entitySet(entitySet).build();
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
new file mode 100644
index 0000000..d476e1a
--- /dev/null
+++ b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.data;
+
+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.LinkedComplexValue;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
+import org.apache.olingo.commons.api.edm.EdmElement;
+import org.apache.olingo.commons.api.edm.EdmEntityContainer;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
+import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ */
+public class DataProviderTest {
+
+  private final Edm edm = OData.newInstance().createEdm(new EdmTechProvider());
+  private final EdmEntityContainer entityContainer = edm.getEntityContainer(
+          new FullQualifiedName("com.sap.odata.test1", "Container"));
+
+  private final EdmEntitySet esAllPrim;
+  private final EdmEntitySet esCompAllPrim;
+  private final EdmEntitySet esCollAllPrim;
+  private final EdmEntitySet esMixPrimCollAllPrim;
+
+  public DataProviderTest() {
+    esAllPrim = entityContainer.getEntitySet("ESAllPrim");
+    esCompAllPrim = entityContainer.getEntitySet("ESCompAllPrim");
+    esCollAllPrim = entityContainer.getEntitySet("ESCollAllPrim");
+    esMixPrimCollAllPrim = entityContainer.getEntitySet("ESMixPrimCollComp");
+  }
+
+  @Test
+  public void esAllPrimEntity() throws Exception {
+    DataProvider jdp = getDataProvider();
+    Entity first = jdp.readAll(esAllPrim).getEntities().get(0);
+
+    Assert.assertEquals(16, first.getProperties().size());
+  }
+
+  @Test
+  public void esAllPrim() throws Exception {
+    DataProvider jdp = getDataProvider();
+    EntitySet outSet = jdp.readAll(esAllPrim);
+
+    Assert.assertEquals(3, outSet.getEntities().size());
+    Entity first = outSet.getEntities().get(0);
+    Assert.assertEquals(16, first.getProperties().size());
+    Assert.assertEquals(16, outSet.getEntities().get(1).getProperties().size());
+    Assert.assertEquals(16, outSet.getEntities().get(2).getProperties().size());
+  }
+
+  @Test
+  public void esCollAllPrim() throws Exception {
+    DataProvider jdp = getDataProvider();
+    EntitySet outSet = jdp.readAll(esCollAllPrim);
+
+    Assert.assertEquals(3, outSet.getEntities().size());
+    Assert.assertEquals(17, outSet.getEntities().get(0).getProperties().size());
+    Property list = outSet.getEntities().get(0).getProperties().get(1);
+    Assert.assertTrue(list.isCollection());
+    Assert.assertEquals(3, list.asCollection().size());
+    Assert.assertEquals(17, outSet.getEntities().get(1).getProperties().size());
+    Assert.assertEquals(17, outSet.getEntities().get(2).getProperties().size());
+  }
+
+  @Test
+  public void esCompAllPrim() throws Exception {
+    DataProvider jdp = getDataProvider();
+    EntitySet outSet = jdp.readAll(esCompAllPrim);
+
+    Assert.assertEquals(3, outSet.getEntities().size());
+    Assert.assertEquals(2, outSet.getEntities().get(0).getProperties().size());
+    Property complex = outSet.getEntities().get(0).getProperties().get(1);
+    Assert.assertTrue(complex.isLinkedComplex());
+    Assert.assertEquals(16, complex.asLinkedComplex().getValue().size());
+    Assert.assertEquals(2, outSet.getEntities().get(1).getProperties().size());
+    Assert.assertEquals(2, outSet.getEntities().get(2).getProperties().size());
+  }
+
+  @Test
+  public void esMixPrimCollComp() throws Exception {
+    DataProvider jdp = getDataProvider();
+    EntitySet outSet = jdp.readAll(esMixPrimCollAllPrim);
+
+    Assert.assertEquals(3, outSet.getEntities().size());
+    Assert.assertEquals(4, outSet.getEntities().get(0).getProperties().size());
+    Property complex = outSet.getEntities().get(0).getProperties().get(2);
+    Assert.assertTrue(complex.isLinkedComplex());
+    Assert.assertEquals(2, complex.asLinkedComplex().getValue().size());
+    Property complexCollection = outSet.getEntities().get(0).getProperties().get(3);
+    Assert.assertTrue(complexCollection.isCollection());
+    List<?> linkedComplexValues = complexCollection.asCollection();
+    Assert.assertEquals(3, linkedComplexValues.size());
+    LinkedComplexValue linkedComplexValue = (LinkedComplexValue) linkedComplexValues.get(0);
+    Assert.assertEquals(2, linkedComplexValue.getValue().size());
+    Property lcProp = linkedComplexValue.getValue().get(0);
+    Assert.assertFalse(lcProp.isCollection());
+    Assert.assertEquals(Integer.valueOf("123"), lcProp.getValue());
+    //
+    Assert.assertEquals(4, outSet.getEntities().get(1).getProperties().size());
+    Assert.assertEquals(4, outSet.getEntities().get(2).getProperties().size());
+  }
+
+  private DataProvider getDataProvider() throws DataProvider.DataProviderException {
+    OData odata = OData.newInstance();
+    Edm edm = odata.createEdm(new EdmTechProvider());
+    return new DataProvider(edm);
+  }
+
+  @Test
+  public void edm() {
+    OData odata = OData.newInstance();
+    Edm edm = odata.createEdm(new EdmTechProvider());
+    EdmEntitySet edmEntitySet =
+        edm.getEntityContainer(ContainerProvider.nameContainer).getEntitySet("ESCompAllPrim");
+
+    EdmEntityType et = edmEntitySet.getEntityType();
+    printType(edm, et);
+  }
+
+  private void printType(Edm edm, EdmStructuredType type) {
+
+    List<String> propNames = type.getPropertyNames();
+
+    for (String propName : propNames) {
+      EdmElement element = type.getProperty(propName);
+      if(element instanceof EdmProperty) {
+        EdmProperty property = (EdmProperty) element;
+        if(property.isPrimitive()) {
+          System.out.println("Primitive name/type: " + property.getName() + "/" + property.getType());
+        } else {
+          // recursion
+          EdmComplexType complex = edm.getComplexType(property.getType().getFullQualifiedName());
+          System.out.println("Complex name/type [" + property.getName() + "/" + property.getType() + "]");
+          printType(edm, complex);
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java
deleted file mode 100644
index 2324dc0..0000000
--- a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java
+++ /dev/null
@@ -1,196 +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.tecsvc.data;
-
-import org.apache.olingo.commons.api.data.ContextURL;
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntitySet;
-import org.apache.olingo.commons.api.data.LinkedComplexValue;
-import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmComplexType;
-import org.apache.olingo.commons.api.edm.EdmElement;
-import org.apache.olingo.commons.api.edm.EdmEntityContainer;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
-import org.apache.olingo.commons.api.edm.EdmProperty;
-import org.apache.olingo.commons.api.edm.EdmStructuredType;
-import org.apache.olingo.commons.api.edm.FullQualifiedName;
-import org.apache.olingo.commons.api.format.ODataFormat;
-import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
-import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
-import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.io.InputStream;
-import java.util.List;
-
-/**
- */
-public class JsonDataProviderTest {
-
-  private final Edm edm = OData.newInstance().createEdm(new EdmTechProvider());
-  private final EdmEntityContainer entityContainer = edm.getEntityContainer(
-          new FullQualifiedName("com.sap.odata.test1", "Container"));
-
-  private final EdmEntitySet esAllPrim;
-  private final EdmEntitySet esCompAllPrim;
-  private final EdmEntitySet esCollAllPrim;
-  private final EdmEntitySet esMixPrimCollAllPrim;
-
-  public JsonDataProviderTest() {
-    esAllPrim = entityContainer.getEntitySet("ESAllPrim");
-    esCompAllPrim = entityContainer.getEntitySet("ESCompAllPrim");
-    esCollAllPrim = entityContainer.getEntitySet("ESCollAllPrim");
-    esMixPrimCollAllPrim = entityContainer.getEntitySet("ESMixPrimCollComp");
-  }
-
-  @Test
-  public void doRoundTrip() throws Exception {
-    doRoundTrip(entityContainer.getEntitySet("ESAllPrim"), 1440);
-    doRoundTrip(entityContainer.getEntitySet("ESCompAllPrim"), 1635);
-    doRoundTrip(entityContainer.getEntitySet("ESCollAllPrim"), 2898);
-    doRoundTrip(entityContainer.getEntitySet("ESMixPrimCollComp"), 1079);
-  }
-
-  @Test
-  public void esAllPrimEntity() throws Exception {
-    DataProvider jdp = getDataProvider();
-    Entity first = jdp.readAll(esAllPrim).getEntities().get(0);
-
-    Assert.assertEquals(16, first.getProperties().size());
-  }
-
-  @Test
-  public void esAllPrim() throws Exception {
-    DataProvider jdp = getDataProvider();
-    EntitySet outSet = jdp.readAll(esAllPrim);
-
-    Assert.assertEquals(3, outSet.getEntities().size());
-    Entity first = outSet.getEntities().get(0);
-    Assert.assertEquals(16, first.getProperties().size());
-    Assert.assertEquals(16, outSet.getEntities().get(1).getProperties().size());
-    Assert.assertEquals(16, outSet.getEntities().get(2).getProperties().size());
-  }
-
-  @Test
-  public void esCollAllPrim() throws Exception {
-    DataProvider jdp = getDataProvider();
-    EntitySet outSet = jdp.readAll(esCollAllPrim);
-
-    Assert.assertEquals(3, outSet.getEntities().size());
-    Assert.assertEquals(17, outSet.getEntities().get(0).getProperties().size());
-    Property list = outSet.getEntities().get(0).getProperties().get(1);
-    Assert.assertTrue(list.isCollection());
-    Assert.assertEquals(3, list.asCollection().size());
-    Assert.assertEquals(17, outSet.getEntities().get(1).getProperties().size());
-    Assert.assertEquals(17, outSet.getEntities().get(2).getProperties().size());
-  }
-
-  @Test
-  public void esCompAllPrim() throws Exception {
-    DataProvider jdp = getDataProvider();
-    EntitySet outSet = jdp.readAll(esCompAllPrim);
-
-    Assert.assertEquals(3, outSet.getEntities().size());
-    Assert.assertEquals(2, outSet.getEntities().get(0).getProperties().size());
-    Property complex = outSet.getEntities().get(0).getProperties().get(1);
-    Assert.assertTrue(complex.isLinkedComplex());
-    Assert.assertEquals(16, complex.asLinkedComplex().getValue().size());
-    Assert.assertEquals(2, outSet.getEntities().get(1).getProperties().size());
-    Assert.assertEquals(2, outSet.getEntities().get(2).getProperties().size());
-  }
-
-  @Test
-  public void esMixPrimCollComp() throws Exception {
-    DataProvider jdp = getDataProvider();
-    EntitySet outSet = jdp.readAll(esMixPrimCollAllPrim);
-
-    Assert.assertEquals(3, outSet.getEntities().size());
-    Assert.assertEquals(4, outSet.getEntities().get(0).getProperties().size());
-    Property complex = outSet.getEntities().get(0).getProperties().get(2);
-    Assert.assertTrue(complex.isLinkedComplex());
-    Assert.assertEquals(2, complex.asLinkedComplex().getValue().size());
-    Property complexCollection = outSet.getEntities().get(0).getProperties().get(3);
-    Assert.assertTrue(complexCollection.isCollection());
-    List<?> linkedComplexValues = complexCollection.asCollection();
-    Assert.assertEquals(3, linkedComplexValues.size());
-    LinkedComplexValue linkedComplexValue = (LinkedComplexValue) linkedComplexValues.get(0);
-    Assert.assertEquals(2, linkedComplexValue.getValue().size());
-    Property lcProp = linkedComplexValue.getValue().get(0);
-    Assert.assertFalse(lcProp.isCollection());
-    Assert.assertEquals(Integer.valueOf("123"), lcProp.getValue());
-    //
-    Assert.assertEquals(4, outSet.getEntities().get(1).getProperties().size());
-    Assert.assertEquals(4, outSet.getEntities().get(2).getProperties().size());
-  }
-
-  private DataProvider getDataProvider() throws DataProvider.DataProviderException {
-    OData odata = OData.newInstance();
-    Edm edm = odata.createEdm(new EdmTechProvider());
-    return new DataProvider(edm);
-  }
-
-  @Test
-  public void edm() {
-    OData odata = OData.newInstance();
-    Edm edm = odata.createEdm(new EdmTechProvider());
-    EdmEntitySet edmEntitySet =
-        edm.getEntityContainer(ContainerProvider.nameContainer).getEntitySet("ESCompAllPrim");
-
-    EdmEntityType et = edmEntitySet.getEntityType();
-    printType(edm, et);
-  }
-
-  private void printType(Edm edm, EdmStructuredType type) {
-
-    List<String> propNames = type.getPropertyNames();
-
-    for (String propName : propNames) {
-      EdmElement element = type.getProperty(propName);
-      if(element instanceof EdmProperty) {
-        EdmProperty property = (EdmProperty) element;
-        if(property.isPrimitive()) {
-          System.out.println("Primitive name/type: " + property.getName() + "/" + property.getType());
-        } else {
-          // recursion
-          EdmComplexType complex = edm.getComplexType(property.getType().getFullQualifiedName());
-          System.out.println("Complex name/type [" + property.getName() + "/" + property.getType() + "]");
-          printType(edm, complex);
-        }
-      }
-    }
-  }
-
-  private void doRoundTrip(EdmEntitySet entitySet, int expectedLength) throws Exception {
-    DataProvider jdp = new DataProvider(edm);
-    EntitySet outSet = jdp.readAll(entitySet);
-
-
-    ODataJsonSerializer serializer = new ODataJsonSerializer(ODataFormat.JSON);
-    ContextURL contextUrl = null;
-    InputStream is = serializer.entitySet(entitySet, outSet, contextUrl);
-
-    StringHelper.Stream stream = StringHelper.toStream(is);
-
-    Assert.assertEquals(expectedLength, stream.asString().length());
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
index 974e338..6ddb14d 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
@@ -23,7 +23,6 @@ import java.net.URI;
 import java.util.Arrays;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.olingo.commons.api.ODataRuntimeException;
 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;
@@ -34,6 +33,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.serialization.ODataSerializerException;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.tecsvc.data.DataProvider;
@@ -54,7 +54,7 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     InputStream result = serializer.entity(edmEntitySet, entity,
-        ContextURL.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
+        ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{"
         + "\"@odata.context\":\"$metadata#ESAllPrim/$entity\","
@@ -83,7 +83,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
-    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
+    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
+        ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()));
     final String expectedResult = "{\"@odata.context\":\"$metadata#ESAllPrim/$entity\","
         + "\"PropertyInt16\":32767,"
         + "\"PropertyString\":null,\"PropertyBoolean\":null,"
@@ -96,20 +97,22 @@ public class ODataJsonSerializerTest {
     Assert.assertEquals(expectedResult, resultString);
   }
 
-  @Test(expected = ODataRuntimeException.class)
+  @Test(expected = ODataSerializerException.class)
   public void entityAllPrimKeyNull() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.getProperties().clear();
-    serializer.entity(edmEntitySet, entity, null);
+    serializer.entity(edmEntitySet, entity,
+        ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
   }
 
-  @Test(expected = ODataRuntimeException.class)
+  @Test(expected = ODataSerializerException.class)
   public void entityWrongData() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.getProperties().get(0).setValue(ValueType.PRIMITIVE, false);
-    serializer.entity(edmEntitySet, entity, null);
+    serializer.entity(edmEntitySet, entity,
+        ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
   }
 
   @Test
@@ -118,7 +121,8 @@ public class ODataJsonSerializerTest {
     EntitySet entitySet = data.readAll(edmEntitySet);
     entitySet.setCount(entitySet.getEntities().size());
     entitySet.setNext(URI.create("/next"));
-    InputStream result = serializer.entitySet(edmEntitySet, entitySet, null);
+    InputStream result = serializer.entitySet(edmEntitySet, entitySet,
+        ContextURL.Builder.create().entitySet(edmEntitySet).build());
     final String resultString = IOUtils.toString(result);
 
     Assert.assertTrue(resultString.matches("\\{"
@@ -141,7 +145,7 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     InputStream result = serializer.entity(edmEntitySet, entity,
-        ContextURL.create().serviceRoot(URI.create("http://host/service/"))
+        ContextURL.Builder.create().serviceRoot(URI.create("http://host/service/"))
             .entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{"
@@ -173,7 +177,8 @@ public class ODataJsonSerializerTest {
   public void entityCompAllPrim() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
-    InputStream result = serializer.entity(edmEntitySet, entity, null);
+    InputStream result = serializer.entity(edmEntitySet, entity,
+        ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{"
         + "\"@odata.context\":\"$metadata#ESCompAllPrim/$entity\","
@@ -203,7 +208,8 @@ public class ODataJsonSerializerTest {
   public void entityMixPrimCollComp() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
-    InputStream result = serializer.entity(edmEntitySet, entity, null);
+    InputStream result = serializer.entity(edmEntitySet, entity,
+        ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{"
         + "\"@odata.context\":\"$metadata#ESMixPrimCollComp/$entity\","
@@ -222,7 +228,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
-    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
+    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
+        ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()));
     final String expectedResult = "{\"@odata.context\":\"$metadata#ESMixPrimCollComp/$entity\","
         + "\"PropertyInt16\":32767,"
         + "\"CollPropertyString\":null,\"PropertyComp\":null,\"CollPropertyComp\":null}";
@@ -234,7 +241,7 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     InputStream result = new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA)
-        .entity(edmEntitySet, entity, ContextURL.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
+        .entity(edmEntitySet, entity, null);
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"}";
     Assert.assertEquals(expectedResult, resultString);
@@ -245,7 +252,7 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
     final EntitySet entitySet = data.readAll(edmEntitySet);
     InputStream result = new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA)
-        .entitySet(edmEntitySet, entitySet, ContextURL.create().entitySet(edmEntitySet).build());
+        .entitySet(edmEntitySet, entitySet, ContextURL.Builder.create().entitySet(edmEntitySet).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{\"value\":["
         + "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"},"
@@ -260,7 +267,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.setMediaETag("theMediaETag");
-    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity, null));
+    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
+        ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()));
     final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia/$entity\","
         + "\"@odata.mediaEtag\":\"theMediaETag\",\"@odata.mediaContentType\":\"image/png\","
         + "\"PropertyInt16\":1}";
@@ -271,7 +279,8 @@ public class ODataJsonSerializerTest {
   public void entitySetMedia() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
     final EntitySet entitySet = data.readAll(edmEntitySet);
-    final String resultString = IOUtils.toString(serializer.entitySet(edmEntitySet, entitySet, null));
+    final String resultString = IOUtils.toString(serializer.entitySet(edmEntitySet, entitySet,
+        ContextURL.Builder.create().entitySet(edmEntitySet).build()));
     final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia\",\"value\":["
         + "{\"@odata.mediaContentType\":\"image/png\",\"PropertyInt16\":1},"
         + "{\"@odata.mediaContentType\":\"image/bmp\",\"PropertyInt16\":2},"

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java
index e804572..821ff47 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java
@@ -18,14 +18,23 @@
  */
 package org.apache.olingo.server.core.serializer.xml;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.olingo.commons.api.ODataException;
-import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.Target;
 import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.serialization.ODataSerializerException;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.edm.provider.Action;
 import org.apache.olingo.server.api.edm.provider.ActionImport;
@@ -51,25 +60,16 @@ import org.apache.olingo.server.core.edm.provider.EdmProviderImpl;
 import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
 import org.junit.Test;
 
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
 public class MetadataDocumentTest {
 
-  @Test(expected = ODataRuntimeException.class)
-  public void metadataOnJsonResultsInException() {
+  @Test(expected = ODataSerializerException.class)
+  public void metadataOnJsonResultsInException() throws Exception {
     ODataSerializer serializer = OData.newInstance().createSerializer(ODataFormat.JSON);
     serializer.metadataDocument(mock(Edm.class));
   }
 
   @Test
-  public void writeMetadataWithEmptyMockedEdm() {
+  public void writeMetadataWithEmptyMockedEdm() throws Exception {
     ODataSerializer serializer = OData.newInstance().createSerializer(ODataFormat.XML);
     Edm edm = mock(Edm.class);
     serializer.metadataDocument(edm);
@@ -145,7 +145,7 @@ public class MetadataDocumentTest {
   }
 
   @Test
-  public void writeMetadataWithTechnicalScenario() {
+  public void writeMetadataWithTechnicalScenario() throws Exception {
     ODataSerializer serializer = OData.newInstance().createSerializer(ODataFormat.XML);
     EdmProviderImpl edm = new EdmProviderImpl(new EdmTechProvider());
     InputStream metadata = serializer.metadataDocument(edm);


[2/2] git commit: [OLINGO-317] Split ContextURL in parser and builder

Posted by mi...@apache.org.
[OLINGO-317] Split ContextURL in parser and builder


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

Branch: refs/heads/master
Commit: c75c29ce051fbc942e218f50b8d60f09e5c3c346
Parents: 5476bad
Author: Michael Bolz <mi...@sap.com>
Authored: Wed Jul 23 10:43:46 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Wed Jul 23 10:52:09 2014 +0200

----------------------------------------------------------------------
 .../olingo/fit/v4/EntitySetTestITCase.java      |   2 +-
 .../fit/v4/JSONFormatConformanceTestITCase.java |   2 +-
 .../core/serialization/AbstractODataBinder.java |  16 +-
 .../core/serialization/v3/ODataBinderImpl.java  |   5 +-
 .../core/serialization/v4/ODataBinderImpl.java  |  21 +-
 .../client/core/v4/ServiceDocumentTest.java     |   2 +-
 .../olingo/commons/api/data/ContextURL.java     | 201 +++---------
 .../apache/olingo/commons/api/data/ResWrap.java |  10 +-
 .../olingo/commons/api/data/ContextURLTest.java | 325 -------------------
 .../core/serialization/AtomSerializer.java      |   8 +-
 .../core/serialization/ContextURLParser.java    | 110 +++++++
 .../serialization/JsonDeltaDeserializer.java    |   4 +-
 .../serialization/JsonEntitySerializer.java     |   2 +-
 .../serialization/JsonEntitySetSerializer.java  |   2 +-
 .../serialization/JsonPropertySerializer.java   |   2 +-
 .../serialization/ContextURLParserTest.java     | 247 ++++++++++++++
 .../server/api/processor/DefaultProcessor.java  |  24 +-
 .../server/api/serializer/ODataSerializer.java  |  14 +-
 .../org/apache/olingo/server/core/Decoder.java  |  90 -----
 .../server/core/ODataExceptionHandler.java      |  10 +-
 .../serializer/json/ODataJsonSerializer.java    |  72 ++--
 .../serializer/utils/ContextURLBuilder.java     |  57 ++++
 .../serializer/utils/ContextURLBuilderTest.java | 123 +++++++
 .../tecsvc/processor/TechnicalProcessor.java    |   7 +-
 .../server/tecsvc/data/DataProviderTest.java    | 170 ++++++++++
 .../tecsvc/data/JsonDataProviderTest.java       | 196 -----------
 .../json/ODataJsonSerializerTest.java           |  41 ++-
 .../serializer/xml/MetadataDocumentTest.java    |  28 +-
 28 files changed, 900 insertions(+), 891 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/fit/src/test/java/org/apache/olingo/fit/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/EntitySetTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/EntitySetTestITCase.java
index cb4f0c3..73c0307 100644
--- a/fit/src/test/java/org/apache/olingo/fit/v4/EntitySetTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/v4/EntitySetTestITCase.java
@@ -56,7 +56,7 @@ public class EntitySetTestITCase extends AbstractTestITCase {
 
     final ResWrap<ODataEntitySet> entitySet = res.getBodyAs(ODataEntitySet.class);
     assertNotNull(entitySet.getPayload());
-    assertTrue(entitySet.getContextURL().getURI().toASCIIString().endsWith("$metadata#People"));
+    assertTrue(entitySet.getContextURL().toASCIIString().endsWith("$metadata#People"));
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
index 75e219d..8c4ef30 100644
--- a/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
@@ -221,7 +221,7 @@ public class JSONFormatConformanceTestITCase extends AbstractTestITCase {
     final ResWrap<Entity> entity =
         client.getDeserializer(ODataFormat.JSON).toEntity(IOUtils.toInputStream(fromSection45_1));
 
-    assertEquals("http://host/service/$metadata#Customers/$entity", entity.getContextURL().getURI().toASCIIString());
+    assertEquals("http://host/service/$metadata#Customers/$entity", entity.getContextURL().toASCIIString());
     assertEquals("W/\"A1FF3E230954908F\"", entity.getMetadataETag());
     assertEquals("W/\"A1FF3E230954908G\"", entity.getPayload().getETag());
     assertEquals("Model.VipCustomer", entity.getPayload().getType());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java
index afc32d0..a33a9d4 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java
@@ -67,6 +67,7 @@ import org.apache.olingo.commons.core.data.EntitySetImpl;
 import org.apache.olingo.commons.core.data.LinkImpl;
 import org.apache.olingo.commons.core.data.PropertyImpl;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+import org.apache.olingo.commons.core.serialization.ContextURLParser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -256,8 +257,9 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
       LOG.debug("EntitySet -> ODataEntitySet:\n{}", writer.toString());
     }
 
-    final URI base = resource.getContextURL() == null
-            ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot();
+    final URI base = resource.getContextURL() == null ?
+        resource.getPayload().getBaseURI() :
+        ContextURLParser.parse(resource.getContextURL()).getServiceRoot();
 
     final URI next = resource.getPayload().getNext();
 
@@ -411,9 +413,11 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
       LOG.debug("EntityResource -> ODataEntity:\n{}", writer.toString());
     }
 
-    final URI base = resource.getContextURL() == null
-            ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot();
-    final EdmType edmType = findType(resource.getContextURL(), resource.getMetadataETag());
+    final ContextURL contextURL = ContextURLParser.parse(resource.getContextURL());
+    final URI base = resource.getContextURL() == null ?
+        resource.getPayload().getBaseURI() :
+        contextURL.getServiceRoot();
+    final EdmType edmType = findType(contextURL, resource.getMetadataETag());
     FullQualifiedName typeName = null;
     if (resource.getPayload().getType() == null) {
       if (edmType != null) {
@@ -511,7 +515,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
   protected abstract CommonODataProperty getODataProperty(EdmType type, Property resource);
 
   protected ODataValue getODataValue(final FullQualifiedName type,
-          final Valuable valuable, final ContextURL contextURL, final String metadataETag) {
+          final Valuable valuable, final URI contextURL, final String metadataETag) {
 
     ODataValue value = null;
     if (valuable.isGeospatial()) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v3/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v3/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v3/ODataBinderImpl.java
index 9410de0..4bd6b08 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v3/ODataBinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v3/ODataBinderImpl.java
@@ -42,6 +42,7 @@ import org.apache.olingo.commons.api.edm.geo.Geospatial;
 import org.apache.olingo.commons.core.data.PropertyImpl;
 import org.apache.olingo.commons.core.domain.v3.ODataPropertyImpl;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+import org.apache.olingo.commons.core.serialization.ContextURLParser;
 
 public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder {
 
@@ -109,8 +110,8 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
 
   @Override
   public ODataProperty getODataProperty(final ResWrap<Property> property) {
-    final EdmTypeInfo typeInfo = buildTypeInfo(property.getContextURL(), property.getMetadataETag(),
-            property.getPayload().getName(), property.getPayload().getType());
+    final EdmTypeInfo typeInfo = buildTypeInfo(ContextURLParser.parse(property.getContextURL()),
+        property.getMetadataETag(), property.getPayload().getName(), property.getPayload().getType());
 
     return new ODataPropertyImpl(property.getPayload().getName(),
             getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(),

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v4/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v4/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v4/ODataBinderImpl.java
index 538ea23..654764e 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v4/ODataBinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/v4/ODataBinderImpl.java
@@ -27,7 +27,6 @@ import org.apache.olingo.client.core.serialization.AbstractODataBinder;
 import org.apache.olingo.client.core.uri.URIUtils;
 import org.apache.olingo.commons.api.data.Annotatable;
 import org.apache.olingo.commons.api.data.Annotation;
-import org.apache.olingo.commons.api.data.ContextURL;
 import org.apache.olingo.commons.api.data.DeletedEntity;
 import org.apache.olingo.commons.api.data.Delta;
 import org.apache.olingo.commons.api.data.DeltaLink;
@@ -75,6 +74,7 @@ import org.apache.olingo.commons.core.domain.v4.ODataDeletedEntityImpl;
 import org.apache.olingo.commons.core.domain.v4.ODataDeltaLinkImpl;
 import org.apache.olingo.commons.core.domain.v4.ODataPropertyImpl;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+import org.apache.olingo.commons.core.serialization.ContextURLParser;
 
 import java.net.URI;
 import java.util.List;
@@ -273,8 +273,9 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
     final ODataEntitySet entitySet = (ODataEntitySet) super.getODataEntitySet(resource);
 
     if (resource.getPayload().getDeltaLink() != null) {
-      final URI base = resource.getContextURL() == null
-              ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot();
+      final URI base = resource.getContextURL() == null ?
+          resource.getPayload().getBaseURI() :
+          ContextURLParser.parse(resource.getContextURL()).getServiceRoot();
       entitySet.setDeltaLink(URIUtils.getURI(base, resource.getPayload().getDeltaLink()));
     }
     odataAnnotations(resource.getPayload(), entitySet);
@@ -307,8 +308,8 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
   @Override
   public ODataProperty getODataProperty(final ResWrap<Property> resource) {
     final Property payload = resource.getPayload();
-    final EdmTypeInfo typeInfo = buildTypeInfo(resource.getContextURL(), resource.getMetadataETag(),
-            payload.getName(), payload.getType());
+    final EdmTypeInfo typeInfo = buildTypeInfo(ContextURLParser.parse(resource.getContextURL()),
+        resource.getMetadataETag(), payload.getName(), payload.getType());
 
     final ODataProperty property = new ODataPropertyImpl(payload.getName(),
             getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(),
@@ -332,7 +333,7 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
 
   @Override
   protected ODataValue getODataValue(final FullQualifiedName type,
-          final Valuable valuable, final ContextURL contextURL, final String metadataETag) {
+          final Valuable valuable, final URI contextURL, final String metadataETag) {
 
     // fixes enum values treated as primitive when no type information is available
     if (client instanceof EdmEnabledODataClient && type != null) {
@@ -359,8 +360,7 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
         edmType = ((EdmEnabledODataClient) client).getEdm(metadataETag).getComplexType(type);
       }
 
-      odataNavigationLinks(edmType, valuable.asLinkedComplex(), lcValue, metadataETag,
-              contextURL == null ? null : contextURL.getURI());
+      odataNavigationLinks(edmType, valuable.asLinkedComplex(), lcValue, metadataETag, contextURL);
       odataAnnotations(valuable.asLinkedComplex(), lcValue);
 
       value = lcValue;
@@ -373,8 +373,9 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
 
   @Override
   public ODataDelta getODataDelta(final ResWrap<Delta> resource) {
-    final URI base = resource.getContextURL() == null
-            ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot();
+    final URI base = resource.getContextURL() == null ?
+        resource.getPayload().getBaseURI() :
+        ContextURLParser.parse(resource.getContextURL()).getServiceRoot();
 
     final URI next = resource.getPayload().getNext();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java
index 711345a..67154ab 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ServiceDocumentTest.java
@@ -48,7 +48,7 @@ public class ServiceDocumentTest extends AbstractTest {
     ResWrap<ServiceDocument> service = getClient().getDeserializer(format).toServiceDocument(
             getClass().getResourceAsStream("serviceDocument." + getFileExtension(format)));
 
-    assertEquals(URI.create("http://host/service/$metadata"), service.getContextURL().getURI());
+    assertEquals(URI.create("http://host/service/$metadata"), service.getContextURL());
     assertEquals("W/\"MjAxMy0wNS0xM1QxNDo1NFo=\"", service.getMetadataETag());
 
     final ODataServiceDocument serviceDocument = getClient().getBinder().getODataServiceDocument(service.getPayload());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java
index 91ab86f..f8095fb 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java
@@ -18,41 +18,29 @@
  */
 package org.apache.olingo.commons.api.data;
 
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.commons.api.Constants;
+import java.net.URI;
+
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 
-import java.net.URI;
-
 /**
- * High-level representation of a context URL, built from the string value returned by a service; provides access to the
- * various components of the context URL, defined in the <a
+ * High-level representation of a context URL,
+ * built from the string value returned by a service;
+ * provides access to the various components of the context URL, defined in the <a
  * href="http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793655">
  * protocol specification</a>.
  */
 public class ContextURL {
 
-  private URI uri;
-
   private URI serviceRoot;
-
   private String entitySetOrSingletonOrType;
-
   private String derivedEntity;
-
   private String selectList;
-
   private String navOrPropertyPath;
 
   public enum Suffix {
-
-    ENTITY("$entity"),
-    REFERENCE("$ref"),
-    DELTA("$delta"),
-    DELTA_DELETED_ENTITY("$deletedEntity"),
-    DELTA_LINK("$link"),
-    DELTA_DELETED_LINK("$deletedLink");
+    ENTITY("$entity"), REFERENCE("$ref"),
+    DELTA("$delta"), DELTA_DELETED_ENTITY("$deletedEntity"), DELTA_LINK("$link"), DELTA_DELETED_LINK("$deletedLink");
 
     private final String representation;
 
@@ -64,92 +52,12 @@ public class ContextURL {
       return representation;
     }
   }
+
   private Suffix suffix;
 
   private ContextURL() {
   }
 
-  public static ContextURL getInstance(final URI contextURL) {
-    final ContextURL instance = new ContextURL();
-    instance.uri = contextURL;
-
-    String contextURLasString = instance.uri.toASCIIString();
-
-    if (contextURLasString.endsWith("/$entity") || contextURLasString.endsWith("/@Element")) {
-      instance.suffix = Suffix.ENTITY;
-      contextURLasString = contextURLasString.replace("/$entity", StringUtils.EMPTY)
-              .replace("/@Element", StringUtils.EMPTY);
-    } else if (contextURLasString.endsWith("/$ref")) {
-      instance.suffix = Suffix.REFERENCE;
-      contextURLasString = contextURLasString.replace("/$ref", StringUtils.EMPTY);
-    } else if (contextURLasString.endsWith("/$delta")) {
-      instance.suffix = Suffix.DELTA;
-      contextURLasString = contextURLasString.replace("/$delta", StringUtils.EMPTY);
-    } else if (contextURLasString.endsWith("/$deletedEntity")) {
-      instance.suffix = Suffix.DELTA_DELETED_ENTITY;
-      contextURLasString = contextURLasString.replace("/$deletedEntity", StringUtils.EMPTY);
-    } else if (contextURLasString.endsWith("/$link")) {
-      instance.suffix = Suffix.DELTA_LINK;
-      contextURLasString = contextURLasString.replace("/$link", StringUtils.EMPTY);
-    } else if (contextURLasString.endsWith("/$deletedLink")) {
-      instance.suffix = Suffix.DELTA_DELETED_LINK;
-      contextURLasString = contextURLasString.replace("/$deletedLink", StringUtils.EMPTY);
-    }
-
-    instance.serviceRoot = URI.create(StringUtils.substringBefore(contextURLasString, Constants.METADATA));
-
-    final String rest = StringUtils.substringAfter(contextURLasString, Constants.METADATA + "#");
-
-    String firstToken;
-    if (rest.startsWith("Collection(")) {
-      firstToken = rest.substring(0, rest.indexOf(')') + 1);
-      instance.entitySetOrSingletonOrType = firstToken;
-    } else {
-      final int openParIdx = rest.indexOf('(');
-      if (openParIdx == -1) {
-        firstToken = StringUtils.substringBefore(rest, "/");
-
-        instance.entitySetOrSingletonOrType = firstToken;
-      } else {
-        firstToken = StringUtils.substringBeforeLast(rest, ")") + ")";
-
-        instance.entitySetOrSingletonOrType = firstToken.substring(0, openParIdx);
-        final int commaIdx = firstToken.indexOf(',');
-        if (commaIdx != -1) {
-          instance.selectList = firstToken.substring(openParIdx + 1, firstToken.length() - 1);
-        }
-      }
-    }
-
-    final int slashIdx = instance.entitySetOrSingletonOrType.lastIndexOf('/');
-    if (slashIdx != -1 && instance.entitySetOrSingletonOrType.substring(slashIdx + 1).indexOf('.') != -1) {
-      final String clone = instance.entitySetOrSingletonOrType;
-      instance.entitySetOrSingletonOrType = clone.substring(0, slashIdx);
-      instance.derivedEntity = clone.substring(slashIdx + 1);
-    }
-
-    if (!firstToken.equals(rest)) {
-      final String[] pathElems = StringUtils.substringAfter(rest, "/").split("/");
-      if (pathElems.length > 0 && pathElems[0].length() > 0) {
-        if (pathElems[0].indexOf('.') == -1) {
-          instance.navOrPropertyPath = pathElems[0];
-        } else {
-          instance.derivedEntity = pathElems[0];
-        }
-
-        if (pathElems.length > 1) {
-          instance.navOrPropertyPath = pathElems[1];
-        }
-      }
-    }
-
-    return instance;
-  }
-
-  public URI getURI() {
-    return uri;
-  }
-
   public URI getServiceRoot() {
     return serviceRoot;
   }
@@ -170,6 +78,10 @@ public class ContextURL {
     return navOrPropertyPath;
   }
 
+  public Suffix getSuffix() {
+    return suffix;
+  }
+
   public boolean isEntity() {
     return suffix == Suffix.ENTITY;
   }
@@ -194,90 +106,59 @@ public class ContextURL {
     return suffix == Suffix.DELTA_DELETED_LINK;
   }
 
-  public static final class ContextURLBuilder {
+  public static final class Builder {
 
     private ContextURL contextURL = new ContextURL();
 
-    private ContextURLBuilder() {
+    private Builder() {
+    }
+
+    public static final Builder create() {
+      return new Builder();
     }
 
-    public ContextURLBuilder serviceRoot(final URI serviceRoot) {
+    public Builder serviceRoot(final URI serviceRoot) {
       contextURL.serviceRoot = serviceRoot;
       return this;
     }
 
-    public ContextURLBuilder entitySet(final EdmEntitySet entitySet) {
+    public Builder entitySet(final EdmEntitySet entitySet) {
       contextURL.entitySetOrSingletonOrType = entitySet.getName();
       return this;
     }
 
-    public ContextURLBuilder derived(final EdmEntityType derivedType) {
-      contextURL.derivedEntity = derivedType.getFullQualifiedName().getFullQualifiedNameAsString();
+    public Builder entitySetOrSingletonOrType(final String entitySetOrSingletonOrType) {
+      contextURL.entitySetOrSingletonOrType = entitySetOrSingletonOrType;
       return this;
     }
 
-    public ContextURLBuilder suffix(final Suffix suffix) {
-      contextURL.suffix = suffix;
+    public Builder derived(final EdmEntityType derivedType) {
+      contextURL.derivedEntity = derivedType.getFullQualifiedName().getFullQualifiedNameAsString();
       return this;
     }
 
-    public ContextURL build() {
-      final StringBuilder result = new StringBuilder();
-      if (contextURL.serviceRoot != null) {
-        result.append(contextURL.serviceRoot);
-      }
-      result.append(Constants.METADATA);
-      if (contextURL.entitySetOrSingletonOrType != null) {
-        result.append('#').append(contextURL.entitySetOrSingletonOrType);
-      }
-      if (contextURL.derivedEntity != null) {
-        if (contextURL.entitySetOrSingletonOrType == null) {
-          throw new IllegalArgumentException("ContextURL: Derived Type without anything to derive from!");
-        }
-        result.append('/').append(contextURL.derivedEntity);
-      }
-      if (contextURL.suffix == Suffix.REFERENCE) {
-        if (contextURL.entitySetOrSingletonOrType != null) {
-          throw new IllegalArgumentException("ContextURL: $ref with Entity Set");
-        }
-        result.append('#').append(contextURL.suffix.getRepresentation());
-      } else if (contextURL.suffix != null) {
-        if (contextURL.entitySetOrSingletonOrType == null) {
-          throw new IllegalArgumentException("ContextURL: Suffix without preceding Entity Set!");
-        }
-        result.append('/').append(contextURL.suffix.getRepresentation());
-      }
-      contextURL.uri = URI.create(result.toString());
-      return contextURL;
+    public Builder derivedEntity(final String derivedEntity) {
+      contextURL.derivedEntity = derivedEntity;
+      return this;
     }
-  }
-
-  public static final ContextURLBuilder create() {
-    return new ContextURLBuilder();
-  }
 
-  @Override
-  public boolean equals(final Object obj) {
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
+    public Builder navOrPropertyPath(final String navOrPropertyPath) {
+      contextURL.navOrPropertyPath = navOrPropertyPath;
+      return this;
     }
-    final ContextURL other = (ContextURL) obj;
-    if (uri != other.uri && (uri == null || !uri.equals(other.uri))) {
-      return false;
+
+    public Builder selectList(final String selectList) {
+      contextURL.selectList = selectList;
+      return this;
     }
-    return true;
-  }
 
-  @Override
-  public int hashCode() {
-    return uri.hashCode();
-  }
+    public Builder suffix(final Suffix suffix) {
+      contextURL.suffix = suffix;
+      return this;
+    }
 
-  @Override
-  public String toString() {
-    return uri.toString();
+    public ContextURL build() {
+      return contextURL;
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ResWrap.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ResWrap.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ResWrap.java
index 1bd1a38..06e889f 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ResWrap.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ResWrap.java
@@ -27,17 +27,11 @@ import java.net.URI;
  */
 public class ResWrap<T> {
 
-  private final ContextURL contextURL;
-
+  private final URI contextURL;
   private final String metadataETag;
-
   private final T payload;
 
   public ResWrap(final URI contextURL, final String metadataETag, final T payload) {
-    this(contextURL == null ? null : ContextURL.getInstance(contextURL), metadataETag, payload);
-  }
-
-  public ResWrap(final ContextURL contextURL, final String metadataETag, final T payload) {
     this.contextURL = contextURL;
     this.metadataETag = metadataETag;
     this.payload = payload;
@@ -55,7 +49,7 @@ public class ResWrap<T> {
    * 
    * @return context URL.
    */
-  public ContextURL getContextURL() {
+  public URI getContextURL() {
     return contextURL;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-api/src/test/java/org/apache/olingo/commons/api/data/ContextURLTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/test/java/org/apache/olingo/commons/api/data/ContextURLTest.java b/lib/commons-api/src/test/java/org/apache/olingo/commons/api/data/ContextURLTest.java
deleted file mode 100644
index abef744..0000000
--- a/lib/commons-api/src/test/java/org/apache/olingo/commons/api/data/ContextURLTest.java
+++ /dev/null
@@ -1,325 +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.commons.api.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.olingo.commons.api.data.ContextURL.Suffix;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
-import org.apache.olingo.commons.api.edm.FullQualifiedName;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.net.URI;
-
-public class ContextURLTest {
-
-  @Test
-  public void collectionOfEntities() {
-    ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers"));
-
-    assertEquals(URI.create("http://host/service/"), contextURL.getServiceRoot());
-    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-
-    contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Orders(4711)/Items"));
-
-    assertEquals("Orders", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertEquals("Items", contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-
-    contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Me/Folders('Inbox')/Messages"));
-
-    assertEquals("Me/Folders", contextURL.getEntitySetOrSingletonOrType());
-    assertEquals("Messages", contextURL.getNavOrPropertyPath());
-  }
-
-  @Test
-  public void entity() {
-    ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers/$entity"));
-
-    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertTrue(contextURL.isEntity());
-
-    contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Orders(4711)/Items/$entity"));
-
-    assertEquals("Orders", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertEquals("Items", contextURL.getNavOrPropertyPath());
-    assertTrue(contextURL.isEntity());
-
-    // v3
-    contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Products/@Element"));
-
-    assertEquals("Products", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertTrue(contextURL.isEntity());
-  }
-
-  @Test
-  public void singleton() {
-    ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Contoso"));
-
-    assertEquals("Contoso", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void collectionOfDerivedEntities() {
-    final ContextURL contextURL = ContextURL.getInstance(
-            URI.create("http://host/service/$metadata#Customers/Model.VipCustomer"));
-
-    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
-    assertEquals("Model.VipCustomer", contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void derivedEntity() {
-    final ContextURL contextURL = ContextURL.getInstance(
-            URI.create("http://host/service/$metadata#Customers/Model.VipCustomer/$entity"));
-
-    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
-    assertEquals("Model.VipCustomer", contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertTrue(contextURL.isEntity());
-  }
-
-  @Test
-  public void collectionOfProjectedEntities() {
-    final ContextURL contextURL = ContextURL.getInstance(
-            URI.create("http://host/service/$metadata#Customers(Address,Orders)"));
-
-    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertEquals("Address,Orders", contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void projectedEntity() {
-    ContextURL contextURL = ContextURL.getInstance(
-            URI.create("http://host/service/$metadata#Customers(Name,Rating)/$entity"));
-
-    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertEquals("Name,Rating", contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertTrue(contextURL.isEntity());
-
-    contextURL = ContextURL.getInstance(
-            URI.create("http://host/service/$metadata#Customers(Name,Address/Country)"));
-
-    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertEquals("Name,Address/Country", contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void collectionOfProjectedExpandedEntities() {
-    final ContextURL contextURL = ContextURL.getInstance(
-            URI.create("http://host/service/$metadata#Employees/"
-                    + "Sales.Manager(DirectReports,DirectReports+(FirstName,LastName))"));
-
-    assertEquals("Employees", contextURL.getEntitySetOrSingletonOrType());
-    assertEquals("Sales.Manager", contextURL.getDerivedEntity());
-    assertEquals("DirectReports,DirectReports+(FirstName,LastName)", contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void propertyValue() {
-    final ContextURL contextURL = ContextURL.getInstance(
-            URI.create("http://host/service/$metadata#Customers(1)/Addresses"));
-
-    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertEquals("Addresses", contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void CollectionOfComplexOrPrimitiveTypes() {
-    final ContextURL contextURL = ContextURL.getInstance(
-            URI.create("http://host/service/$metadata#Collection(Edm.String)"));
-
-    assertEquals("Collection(Edm.String)", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void complexOrPrimitiveType() {
-    ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Edm.String"));
-
-    assertEquals("Edm.String", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-
-    contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#ODataDemo.Address"));
-
-    assertEquals("ODataDemo.Address", contextURL.getEntitySetOrSingletonOrType());
-    assertNull(contextURL.getDerivedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void reference() {
-    ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers/$ref"));
-    assertTrue(contextURL.isReference());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-    assertFalse(contextURL.isDelta());
-  }
-
-  @Test
-  public void delta() {
-    ContextURL contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers/$delta"));
-    assertTrue(contextURL.isDelta());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-
-    contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers/$deletedLink"));
-    assertTrue(contextURL.isDeltaDeletedLink());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-
-    contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers/$link"));
-    assertTrue(contextURL.isDeltaLink());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-
-    contextURL = ContextURL.getInstance(URI.create("http://host/service/$metadata#Customers/$deletedEntity"));
-    assertTrue(contextURL.isDeltaDeletedEntity());
-    assertNull(contextURL.getSelectList());
-    assertNull(contextURL.getNavOrPropertyPath());
-    assertFalse(contextURL.isEntity());
-  }
-
-  @Test
-  public void buildServiceDocument() {
-    ContextURL contextURL = ContextURL.create().serviceRoot(URI.create("http://host/service/")).build();
-    assertEquals("http://host/service/$metadata", contextURL.getURI().toASCIIString());
-  }
-
-  @Test
-  public void buildRelative() {
-    ContextURL contextURL = ContextURL.create().build();
-    assertEquals("$metadata", contextURL.getURI().toASCIIString());
-  }
-
-  @Test
-  public void buildEntitySet() {
-    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
-    Mockito.when(entitySet.getName()).thenReturn("Customers");
-    ContextURL contextURL = ContextURL.create().serviceRoot(URI.create("http://host/service/"))
-            .entitySet(entitySet)
-            .build();
-    assertEquals("http://host/service/$metadata#Customers", contextURL.getURI().toASCIIString());
-  }
-
-  @Test
-  public void buildDerivedEntitySet() {
-    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
-    Mockito.when(entitySet.getName()).thenReturn("Customers");
-    EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
-    Mockito.when(derivedType.getFullQualifiedName()).thenReturn(new FullQualifiedName("Model", "VipCustomer"));
-    ContextURL contextURL = ContextURL.create().serviceRoot(URI.create("http://host/service/"))
-            .entitySet(entitySet)
-            .derived(derivedType)
-            .build();
-    assertEquals("http://host/service/$metadata#Customers/Model.VipCustomer", contextURL.getURI().toASCIIString());
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void buildDerivedEntitySetWithoutEntitySet() {
-    EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
-    Mockito.when(derivedType.getFullQualifiedName()).thenReturn(new FullQualifiedName("Model", "VipCustomer"));
-    ContextURL.create().derived(derivedType).build();
-  }
-
-  @Test
-  public void buildDerivedEntity() {
-    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
-    Mockito.when(entitySet.getName()).thenReturn("Customers");
-    EdmEntityType derivedType = Mockito.mock(EdmEntityType.class);
-    Mockito.when(derivedType.getFullQualifiedName()).thenReturn(new FullQualifiedName("Model", "VipCustomer"));
-    ContextURL contextURL = ContextURL.create().serviceRoot(URI.create("http://host/service/"))
-            .entitySet(entitySet)
-            .derived(derivedType)
-            .suffix(Suffix.ENTITY)
-            .build();
-    assertEquals("http://host/service/$metadata#Customers/Model.VipCustomer/$entity",
-            contextURL.getURI().toASCIIString());
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void buildSuffixWithoutEntitySet() {
-    ContextURL.create().suffix(Suffix.ENTITY).build();
-  }
-
-  @Test
-  public void buildReference() {
-    ContextURL contextURL = ContextURL.create().suffix(Suffix.REFERENCE).build();
-    assertEquals("$metadata#$ref", contextURL.getURI().toASCIIString());
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void buildReferenceWithEntitySet() {
-    EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
-    Mockito.when(entitySet.getName()).thenReturn("Customers");
-    ContextURL.create().entitySet(entitySet).suffix(Suffix.REFERENCE).build();
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
index 79ffd13..5475064 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
@@ -19,9 +19,11 @@
 package org.apache.olingo.commons.core.serialization;
 
 import com.fasterxml.aalto.stax.OutputFactoryImpl;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Annotation;
+import org.apache.olingo.commons.api.data.ContextURL;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.data.Link;
@@ -49,6 +51,7 @@ import javax.xml.XMLConstants;
 import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
+
 import java.io.Writer;
 import java.util.Collections;
 import java.util.List;
@@ -549,7 +552,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
       final XMLStreamWriter writer, final ResWrap<T> container) throws XMLStreamException {
 
     if (container.getContextURL() != null) {
-      String base = container.getContextURL().getServiceRoot().toASCIIString();
+      final ContextURL contextURL = ContextURLParser.parse(container.getContextURL());
+      String base = contextURL.getServiceRoot().toASCIIString();
       if (container.getPayload() instanceof EntitySet) {
         ((EntitySetImpl) container.getPayload()).setBaseURI(base);
       }
@@ -558,7 +562,7 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
       }
 
       writer.writeAttribute(namespaceMetadata, Constants.CONTEXT,
-          container.getContextURL().getURI().toASCIIString());
+          container.getContextURL().toASCIIString());
     }
 
     if (StringUtils.isNotBlank(container.getMetadataETag())) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java
new file mode 100644
index 0000000..3598af7
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java
@@ -0,0 +1,110 @@
+/*
+ * 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.commons.core.serialization;
+
+import java.net.URI;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.ContextURL.Suffix;
+
+public class ContextURLParser {
+  public static ContextURL parse(final URI contextURL) {
+    if (contextURL == null) {
+      return null;
+    }
+
+    ContextURL.Builder builder = ContextURL.Builder.create();
+
+    String contextURLasString = contextURL.toASCIIString();
+
+    if (contextURLasString.endsWith("/$entity") || contextURLasString.endsWith("/@Element")) {
+      builder.suffix(Suffix.ENTITY);
+      contextURLasString = contextURLasString.replace("/$entity", StringUtils.EMPTY)
+              .replace("/@Element", StringUtils.EMPTY);
+    } else if (contextURLasString.endsWith("/$ref")) {
+      builder.suffix(Suffix.REFERENCE);
+      contextURLasString = contextURLasString.replace("/$ref", StringUtils.EMPTY);
+    } else if (contextURLasString.endsWith("/$delta")) {
+      builder.suffix(Suffix.DELTA);
+      contextURLasString = contextURLasString.replace("/$delta", StringUtils.EMPTY);
+    } else if (contextURLasString.endsWith("/$deletedEntity")) {
+      builder.suffix(Suffix.DELTA_DELETED_ENTITY);
+      contextURLasString = contextURLasString.replace("/$deletedEntity", StringUtils.EMPTY);
+    } else if (contextURLasString.endsWith("/$link")) {
+      builder.suffix(Suffix.DELTA_LINK);
+      contextURLasString = contextURLasString.replace("/$link", StringUtils.EMPTY);
+    } else if (contextURLasString.endsWith("/$deletedLink")) {
+      builder.suffix(Suffix.DELTA_DELETED_LINK);
+      contextURLasString = contextURLasString.replace("/$deletedLink", StringUtils.EMPTY);
+    }
+
+    builder.serviceRoot(URI.create(StringUtils.substringBefore(contextURLasString, Constants.METADATA)));
+
+    final String rest = StringUtils.substringAfter(contextURLasString, Constants.METADATA + "#");
+
+    String firstToken;
+    String entitySetOrSingletonOrType = null;
+    if (rest.startsWith("Collection(")) {
+      firstToken = rest.substring(0, rest.indexOf(')') + 1);
+      entitySetOrSingletonOrType = firstToken;
+    } else {
+      final int openParIdx = rest.indexOf('(');
+      if (openParIdx == -1) {
+        firstToken = StringUtils.substringBefore(rest, "/");
+
+        entitySetOrSingletonOrType = firstToken;
+      } else {
+        firstToken = StringUtils.substringBeforeLast(rest, ")") + ")";
+
+        entitySetOrSingletonOrType = firstToken.substring(0, openParIdx);
+        final int commaIdx = firstToken.indexOf(',');
+        if (commaIdx != -1) {
+          builder.selectList(firstToken.substring(openParIdx + 1, firstToken.length() - 1));
+        }
+      }
+    }
+    builder.entitySetOrSingletonOrType(entitySetOrSingletonOrType);
+
+    final int slashIdx = entitySetOrSingletonOrType.lastIndexOf('/');
+    if (slashIdx != -1 && entitySetOrSingletonOrType.substring(slashIdx + 1).indexOf('.') != -1) {
+      final String clone = entitySetOrSingletonOrType;
+      builder.entitySetOrSingletonOrType(clone.substring(0, slashIdx));
+      builder.derivedEntity(clone.substring(slashIdx + 1));
+    }
+
+    if (!firstToken.equals(rest)) {
+      final String[] pathElems = StringUtils.substringAfter(rest, "/").split("/");
+      if (pathElems.length > 0 && pathElems[0].length() > 0) {
+        if (pathElems[0].indexOf('.') == -1) {
+          builder.navOrPropertyPath(pathElems[0]);
+        } else {
+          builder.derivedEntity(pathElems[0]);
+        }
+
+        if (pathElems.length > 1) {
+          builder.navOrPropertyPath(pathElems[1]);
+        }
+      }
+    }
+
+    return builder.build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java
index 3505df9..a9d4fb4 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonDeltaDeserializer.java
@@ -70,8 +70,8 @@ public class JsonDeltaDeserializer extends JsonDeserializer {
       JsonEntityDeserializer entityDeserializer = new JsonEntityDeserializer(version, serverMode);
       for (JsonNode jsonNode : tree.get(Constants.VALUE)) {
         final ObjectNode item = (ObjectNode) jsonNode;
-        final ContextURL itemContextURL = item.hasNonNull(Constants.JSON_CONTEXT)
-            ? ContextURL.getInstance(URI.create(item.get(Constants.JSON_CONTEXT).textValue())) : null;
+        final ContextURL itemContextURL = item.hasNonNull(Constants.JSON_CONTEXT) ?
+            ContextURLParser.parse(URI.create(item.get(Constants.JSON_CONTEXT).textValue())) : null;
         item.remove(Constants.JSON_CONTEXT);
 
         if (itemContextURL == null || itemContextURL.isEntity()) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
index 65fb28e..9396b77 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
@@ -59,7 +59,7 @@ public class JsonEntitySerializer extends JsonSerializer {
       if (container.getContextURL() != null) {
         jgen.writeStringField(version.compareTo(ODataServiceVersion.V40) >= 0
             ? Constants.JSON_CONTEXT : Constants.JSON_METADATA,
-            container.getContextURL().getURI().toASCIIString());
+            container.getContextURL().toASCIIString());
       }
       if (version.compareTo(ODataServiceVersion.V40) >= 0 && StringUtils.isNotBlank(container.getMetadataETag())) {
         jgen.writeStringField(Constants.JSON_METADATA_ETAG, container.getMetadataETag());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java
index fb21520..256376c 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySetSerializer.java
@@ -53,7 +53,7 @@ public class JsonEntitySetSerializer extends JsonSerializer {
       if (container.getContextURL() != null) {
         jgen.writeStringField(version.compareTo(ODataServiceVersion.V40) >= 0
             ? Constants.JSON_CONTEXT : Constants.JSON_METADATA,
-            container.getContextURL().getURI().toASCIIString());
+            container.getContextURL().toASCIIString());
       }
 
       if (version.compareTo(ODataServiceVersion.V40) >= 0 && StringUtils.isNotBlank(container.getMetadataETag())) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java
index feda16b..5b00a6a 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonPropertySerializer.java
@@ -55,7 +55,7 @@ public class JsonPropertySerializer extends JsonSerializer {
     if (serverMode && container.getContextURL() != null) {
       jgen.writeStringField(version.compareTo(ODataServiceVersion.V40) >= 0
           ? Constants.JSON_CONTEXT : Constants.JSON_METADATA,
-          container.getContextURL().getURI().toASCIIString());
+          container.getContextURL().toASCIIString());
     }
 
     if (StringUtils.isNotBlank(property.getType())) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java
new file mode 100644
index 0000000..5a16da2
--- /dev/null
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.commons.core.serialization;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.core.serialization.ContextURLParser;
+import org.junit.Test;
+
+import java.net.URI;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class ContextURLParserTest {
+
+  @Test
+  public void collectionOfEntities() {
+    ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers"));
+
+    assertEquals(URI.create("http://host/service/"), contextURL.getServiceRoot());
+    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+
+    contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Orders(4711)/Items"));
+
+    assertEquals("Orders", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertEquals("Items", contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+
+    contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Me/Folders('Inbox')/Messages"));
+
+    assertEquals("Me/Folders", contextURL.getEntitySetOrSingletonOrType());
+    assertEquals("Messages", contextURL.getNavOrPropertyPath());
+  }
+
+  @Test
+  public void entity() {
+    ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$entity"));
+
+    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertTrue(contextURL.isEntity());
+
+    contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Orders(4711)/Items/$entity"));
+
+    assertEquals("Orders", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertEquals("Items", contextURL.getNavOrPropertyPath());
+    assertTrue(contextURL.isEntity());
+
+    // v3
+    contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Products/@Element"));
+
+    assertEquals("Products", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertTrue(contextURL.isEntity());
+  }
+
+  @Test
+  public void singleton() {
+    ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Contoso"));
+
+    assertEquals("Contoso", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+
+  @Test
+  public void collectionOfDerivedEntities() {
+    final ContextURL contextURL = ContextURLParser.parse(
+        URI.create("http://host/service/$metadata#Customers/Model.VipCustomer"));
+
+    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
+    assertEquals("Model.VipCustomer", contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+
+  @Test
+  public void derivedEntity() {
+    final ContextURL contextURL = ContextURLParser.parse(
+        URI.create("http://host/service/$metadata#Customers/Model.VipCustomer/$entity"));
+
+    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
+    assertEquals("Model.VipCustomer", contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertTrue(contextURL.isEntity());
+  }
+
+  @Test
+  public void collectionOfProjectedEntities() {
+    final ContextURL contextURL = ContextURLParser.parse(
+        URI.create("http://host/service/$metadata#Customers(Address,Orders)"));
+
+    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertEquals("Address,Orders", contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+
+  @Test
+  public void projectedEntity() {
+    ContextURL contextURL = ContextURLParser.parse(
+        URI.create("http://host/service/$metadata#Customers(Name,Rating)/$entity"));
+
+    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertEquals("Name,Rating", contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertTrue(contextURL.isEntity());
+
+    contextURL = ContextURLParser.parse(
+        URI.create("http://host/service/$metadata#Customers(Name,Address/Country)"));
+
+    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertEquals("Name,Address/Country", contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+
+  @Test
+  public void collectionOfProjectedExpandedEntities() {
+    final ContextURL contextURL = ContextURLParser.parse(
+        URI.create("http://host/service/$metadata#Employees/"
+            + "Sales.Manager(DirectReports,DirectReports+(FirstName,LastName))"));
+
+    assertEquals("Employees", contextURL.getEntitySetOrSingletonOrType());
+    assertEquals("Sales.Manager", contextURL.getDerivedEntity());
+    assertEquals("DirectReports,DirectReports+(FirstName,LastName)", contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+
+  @Test
+  public void propertyValue() {
+    final ContextURL contextURL = ContextURLParser.parse(
+        URI.create("http://host/service/$metadata#Customers(1)/Addresses"));
+
+    assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertEquals("Addresses", contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+
+  @Test
+  public void CollectionOfComplexOrPrimitiveTypes() {
+    final ContextURL contextURL = ContextURLParser.parse(
+        URI.create("http://host/service/$metadata#Collection(Edm.String)"));
+
+    assertEquals("Collection(Edm.String)", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+
+  @Test
+  public void complexOrPrimitiveType() {
+    ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Edm.String"));
+
+    assertEquals("Edm.String", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+
+    contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#ODataDemo.Address"));
+
+    assertEquals("ODataDemo.Address", contextURL.getEntitySetOrSingletonOrType());
+    assertNull(contextURL.getDerivedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+
+  @Test
+  public void reference() {
+    ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$ref"));
+    assertTrue(contextURL.isReference());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+    assertFalse(contextURL.isDelta());
+  }
+
+  @Test
+  public void delta() {
+    ContextURL contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$delta"));
+    assertTrue(contextURL.isDelta());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+
+    contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$deletedLink"));
+    assertTrue(contextURL.isDeltaDeletedLink());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+
+    contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$link"));
+    assertTrue(contextURL.isDeltaLink());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+
+    contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Customers/$deletedEntity"));
+    assertTrue(contextURL.isDeltaDeletedEntity());
+    assertNull(contextURL.getSelectList());
+    assertNull(contextURL.getNavOrPropertyPath());
+    assertFalse(contextURL.isEntity());
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
index 548c902..462a803 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/DefaultProcessor.java
@@ -26,6 +26,7 @@ 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.api.serialization.ODataSerializerException;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
@@ -52,22 +53,27 @@ public class DefaultProcessor implements MetadataProcessor, ServiceDocumentProce
   public void readServiceDocument(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
       final ContentType requestedContentType) {
     ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(requestedContentType));
-    InputStream responseEntity = serializer.serviceDocument(edm, request.getRawBaseUri());
-
-    response.setStatusCode(200);
-    response.setContent(responseEntity);
-    response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
 
+    try {
+      response.setContent(serializer.serviceDocument(edm, request.getRawBaseUri()));
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+    } catch (final ODataSerializerException e) {
+      response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+    }
   }
 
   @Override
   public void readMetadata(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
       final ContentType requestedContentType) {
     ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(requestedContentType));
-    InputStream responseEntity = serializer.metadataDocument(edm);
-    response.setStatusCode(200);
-    response.setContent(responseEntity);
-    response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+    try {
+      response.setContent(serializer.metadataDocument(edm));
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+    } catch (final ODataSerializerException e) {
+      response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+    }
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/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 9206b4f..4ec5197 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
@@ -25,24 +25,28 @@ import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.serialization.ODataSerializerException;
 import org.apache.olingo.server.api.ODataServerError;
 
 public interface ODataSerializer {
 
   public static final String DEFAULT_CHARSET = "UTF-8";
 
-  InputStream serviceDocument(Edm edm, String serviceRoot);
+  InputStream serviceDocument(Edm edm, String serviceRoot) throws ODataSerializerException;
 
-  InputStream metadataDocument(Edm edm);
+  InputStream metadataDocument(Edm edm) throws ODataSerializerException;
 
-  InputStream entity(EdmEntitySet edmEntitySet, Entity entity, ContextURL contextURL);
+  InputStream entity(EdmEntitySet edmEntitySet, Entity entity, ContextURL contextURL)
+      throws ODataSerializerException;
 
-  InputStream entitySet(EdmEntitySet edmEntitySet, EntitySet entitySet, ContextURL contextURL);
+  InputStream entitySet(EdmEntitySet edmEntitySet, EntitySet entitySet, ContextURL contextURL)
+      throws ODataSerializerException;
 
   /**
    * Writes an ODataError into an InputStream.
    * @param error the main error
    * @return inputStream containing the OData formatted error
+   * @throws ODataSerializerException 
    */
-  InputStream error(ODataServerError error);
+  InputStream error(ODataServerError error) throws ODataSerializerException;
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-core/src/main/java/org/apache/olingo/server/core/Decoder.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/Decoder.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/Decoder.java
deleted file mode 100644
index e3eb5e9..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/Decoder.java
+++ /dev/null
@@ -1,90 +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.core;
-
-import java.io.UnsupportedEncodingException;
-
-/**
- * Decodes a Java String containing a percent-encoded UTF-8 String value
- * into a Java String (in its internal UTF-16 encoding).
- * 
- */
-public class Decoder {
-
-  /**
-   * Decodes a percent-encoded UTF-8 String value into a Java String
-   * (in its internal UTF-16 encoding).
-   * @param value the encoded String
-   * @return the Java String
-   * @throws IllegalArgumentException if value contains characters not representing UTF-8 bytes
-   * or ends with an unfinished percent-encoded character
-   * @throws NumberFormatException if the two characters after a percent character
-   * are not hexadecimal digits
-   */
-  public static String decode(final String value) throws IllegalArgumentException, NumberFormatException {
-    if (value == null) {
-      return value;
-    }
-
-    // Use a tiny finite-state machine to handle decoding on byte level.
-    // There are only three states:
-    // -2: normal bytes
-    // -1: a byte representing the percent character has been read
-    // >= 0: a byte representing the first half-byte of a percent-encoded byte has been read
-    // The variable holding the state is also used to store the value of the first half-byte.
-    byte[] result = new byte[value.length()];
-    int position = 0;
-    byte encodedPart = -2;
-    for (final char c : value.toCharArray()) {
-      if (c <= Byte.MAX_VALUE) {
-        if (c == '%') {
-          if (encodedPart == -2) {
-            encodedPart = -1;
-          } else {
-            throw new IllegalArgumentException();
-          }
-        } else if (encodedPart == -1) {
-          encodedPart = (byte) c;
-        } else if (encodedPart >= 0) {
-          final int i = Integer.parseInt(String.valueOf(new char[] { (char) encodedPart, c }), 16);
-          if (i >= 0) {
-            result[position++] = (byte) i;
-          } else {
-            throw new NumberFormatException();
-          }
-          encodedPart = -2;
-        } else {
-          result[position++] = (byte) c;
-        }
-      } else {
-        throw new IllegalArgumentException();
-      }
-    }
-
-    if (encodedPart >= 0) {
-      throw new IllegalArgumentException();
-    }
-
-    try {
-      return new String(result, 0, position, "UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHandler.java
index cb2d183..20fffe4 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHandler.java
@@ -18,10 +18,11 @@
  */
 package org.apache.olingo.server.core;
 
-import java.io.InputStream;
 import java.util.Locale;
 
 import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.commons.api.serialization.ODataSerializerException;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.ODataServerError;
@@ -35,7 +36,7 @@ public class ODataExceptionHandler {
 
   public void handle(ODataResponse resp, Exception e) {
     if (resp.getStatusCode() == 0) {
-      resp.setStatusCode(500);
+      resp.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
     }
     ODataServerError error = new ODataServerError();
     if (e instanceof ODataTranslatedException) {
@@ -45,8 +46,9 @@ public class ODataExceptionHandler {
     }
 
     ODataSerializer serializer = OData.newInstance().createSerializer(requestedFormat);
-    InputStream errorStream = serializer.error(error);
-    resp.setContent(errorStream);
+    try {
+      resp.setContent(serializer.error(error));
+    } catch (final ODataSerializerException e1) {}
     // Set header
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c75c29ce/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
index bc4cbc9..d8128a8 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
@@ -23,9 +23,7 @@ import java.io.InputStream;
 import java.util.List;
 
 import org.apache.olingo.commons.api.Constants;
-import org.apache.olingo.commons.api.ODataRuntimeException;
 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.LinkedComplexValue;
@@ -39,10 +37,12 @@ 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.ODataFormat;
+import org.apache.olingo.commons.api.serialization.ODataSerializerException;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 import org.apache.olingo.server.api.ODataServerError;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
+import org.apache.olingo.server.core.serializer.utils.ContextURLBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -61,7 +61,7 @@ public class ODataJsonSerializer implements ODataSerializer {
   }
 
   @Override
-  public InputStream serviceDocument(final Edm edm, final String serviceRoot) {
+  public InputStream serviceDocument(final Edm edm, final String serviceRoot) throws ODataSerializerException {
     CircleStreamBuffer buffer;
     JsonGenerator gen = null;
 
@@ -83,48 +83,49 @@ public class ODataJsonSerializer implements ODataSerializer {
 
     } catch (Exception e) {
       log.error(e.getMessage(), e);
-      throw new ODataRuntimeException(e);
+      throw new ODataSerializerException(e);
     } finally {
       if (gen != null) {
         try {
           gen.close();
         } catch (IOException e) {
-          throw new ODataRuntimeException(e);
+          throw new ODataSerializerException(e);
         }
       }
     }
   }
 
   @Override
-  public InputStream metadataDocument(final Edm edm) {
-    throw new ODataRuntimeException("Metadata in JSON format not supported!");
+  public InputStream metadataDocument(final Edm edm) throws ODataSerializerException {
+    throw new ODataSerializerException("Metadata in JSON format not supported!");
   }
 
   @Override
-  public InputStream error(final ODataServerError error) {
+  public InputStream error(final ODataServerError error) throws ODataSerializerException {
     CircleStreamBuffer buffer = new CircleStreamBuffer();
     try {
       JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
       new ODataErrorSerializer().writeErrorDocument(json, error);
       json.close();
     } catch (final IOException e) {
-      throw new ODataRuntimeException(e);
+      throw new ODataSerializerException(e);
     }
     return buffer.getInputStream();
   }
 
   @Override
   public InputStream entitySet(final EdmEntitySet edmEntitySet, final EntitySet entitySet,
-      final ContextURL contextURL) {
-    final ContextURL entitySetContextURL = contextURL == null ?
-        ContextURL.create().entitySet(edmEntitySet).build() :
-        contextURL;
+      final ContextURL contextURL) throws ODataSerializerException {
     CircleStreamBuffer buffer = new CircleStreamBuffer();
     try {
       JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
       json.writeStartObject();
       if (format != ODataFormat.JSON_NO_METADATA) {
-        json.writeStringField(Constants.JSON_CONTEXT, entitySetContextURL.getURI().toASCIIString());
+        if (contextURL == null) {
+          throw new ODataSerializerException("ContextURL null!");
+        } else {
+          json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
+        }
       }
       if (entitySet.getCount() != null) {
         json.writeNumberField(Constants.JSON_COUNT, entitySet.getCount());
@@ -140,38 +141,39 @@ public class ODataJsonSerializer implements ODataSerializer {
       }
       json.close();
     } catch (final IOException e) {
-      throw new ODataRuntimeException(e);
+      throw new ODataSerializerException(e);
     } catch (final EdmPrimitiveTypeException e) {
-      throw new ODataRuntimeException(e);
+      throw new ODataSerializerException(e);
     }
     return buffer.getInputStream();
   }
 
   @Override
-  public InputStream entity(final EdmEntitySet edmEntitySet, final Entity entity, final ContextURL contextURL) {
-    final ContextURL entityContextURL = contextURL == null ?
-        ContextURL.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build() :
-        contextURL;
+  public InputStream entity(final EdmEntitySet edmEntitySet, final Entity entity, final ContextURL contextURL)
+      throws ODataSerializerException {
+    if (format != ODataFormat.JSON_NO_METADATA && contextURL == null) {
+      throw new ODataSerializerException("ContextURL null!");
+    }
     CircleStreamBuffer buffer = new CircleStreamBuffer();
     try {
       JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
-      writeEntity(edmEntitySet, entity, entityContextURL, json);
+      writeEntity(edmEntitySet, entity, contextURL, json);
       json.close();
     } catch (final IOException e) {
-      throw new ODataRuntimeException(e);
+      throw new ODataSerializerException(e);
     } catch (final EdmPrimitiveTypeException e) {
-      throw new ODataRuntimeException(e);
+      throw new ODataSerializerException(e);
     }
     return buffer.getInputStream();
   }
 
   protected void writeEntity(final EdmEntitySet entitySet, final Entity entity, final ContextURL contextURL,
-      final JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
+      final JsonGenerator json) throws IOException, EdmPrimitiveTypeException, ODataSerializerException {
     final EdmEntityType entityType = entitySet.getEntityType();
     json.writeStartObject();
     if (format != ODataFormat.JSON_NO_METADATA) {
       if (contextURL != null) {
-        json.writeStringField(Constants.JSON_CONTEXT, contextURL.getURI().toASCIIString());
+        json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
       }
       if (entity.getETag() != null) {
         json.writeStringField(Constants.JSON_ETAG, entity.getETag());
@@ -194,11 +196,11 @@ public class ODataJsonSerializer implements ODataSerializer {
   }
 
   protected void writeProperty(final EdmProperty edmProperty, final Property property, final JsonGenerator json)
-      throws IOException, EdmPrimitiveTypeException {
+      throws IOException, EdmPrimitiveTypeException, ODataSerializerException {
     json.writeFieldName(edmProperty.getName());
     if (property == null || property.isNull()) {
       if (edmProperty.isNullable() == Boolean.FALSE) {
-        throw new ODataRuntimeException("Non-nullable property not present!");
+        throw new ODataSerializerException("Non-nullable property not present!");
       } else {
         json.writeNull();
       }
@@ -212,13 +214,13 @@ public class ODataJsonSerializer implements ODataSerializer {
       } else if (property.isComplex()) {
         writeComplexValue(edmProperty, property.asComplex(), json);
       } else {
-        throw new ODataRuntimeException("Property type not yet supported!");
+        throw new ODataSerializerException("Property type not yet supported!");
       }
     }
   }
 
   private void writeCollection(EdmProperty edmProperty, Property property, JsonGenerator json)
-          throws IOException, EdmPrimitiveTypeException {
+          throws IOException, EdmPrimitiveTypeException, ODataSerializerException {
     json.writeStartArray();
     for (Object value : property.asCollection()) {
       switch (property.getValueType()) {
@@ -226,7 +228,7 @@ public class ODataJsonSerializer implements ODataSerializer {
         writePrimitiveValue(edmProperty, value, json);
         break;
       case COLLECTION_GEOSPATIAL:
-        throw new ODataRuntimeException("Property type not yet supported!");
+        throw new ODataSerializerException("Property type not yet supported!");
       case COLLECTION_ENUM:
         json.writeString(value.toString());
         break;
@@ -237,22 +239,22 @@ public class ODataJsonSerializer implements ODataSerializer {
         writeComplexValue(edmProperty, property.asComplex(), json);
         break;
       default:
-        throw new ODataRuntimeException("Property type not yet supported!");
+        throw new ODataSerializerException("Property type not yet supported!");
       }
     }
     json.writeEndArray();
   }
 
   private void writePrimitive(EdmProperty edmProperty, Property property, JsonGenerator json)
-          throws EdmPrimitiveTypeException, IOException {
+          throws EdmPrimitiveTypeException, IOException, ODataSerializerException {
     if (property.isPrimitive()) {
       writePrimitiveValue(edmProperty, property.asPrimitive(), json);
     } else if (property.isGeospatial()) {
-      throw new ODataRuntimeException("Property type not yet supported!");
+      throw new ODataSerializerException("Property type not yet supported!");
     } else if (property.isEnum()) {
       writePrimitiveValue(edmProperty, property.asEnum(), json);
     } else {
-      throw new ODataRuntimeException("Inconsistent property type!");
+      throw new ODataSerializerException("Inconsistent property type!");
     }
   }
 
@@ -280,7 +282,7 @@ public class ODataJsonSerializer implements ODataSerializer {
   }
 
   private void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
-      JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
+      JsonGenerator json) throws IOException, EdmPrimitiveTypeException, ODataSerializerException {
     final EdmComplexType type = (EdmComplexType) edmProperty.getType();
     json.writeStartObject();
     for (final String propertyName : type.getPropertyNames()) {