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/15 15:48:10 UTC

git commit: [OLINGO-317] ContextURL integration

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 0e245e0fb -> b9f4b3c64


[OLINGO-317] ContextURL integration


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

Branch: refs/heads/master
Commit: b9f4b3c64c893d731d6d6ff326486c6667791388
Parents: 0e245e0
Author: Michael Bolz <mi...@sap.com>
Authored: Tue Jul 15 15:38:30 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Tue Jul 15 15:43:43 2014 +0200

----------------------------------------------------------------------
 lib/commons-api/pom.xml                         |  10 +-
 .../apache/olingo/commons/api/Constants.java    |  16 ++-
 .../olingo/commons/api/data/ContextURL.java     | 137 +++++++++++++++----
 .../api/edm/constants/ODataServiceVersion.java  |  30 ++--
 .../olingo/commons/api/data/ContextURLTest.java |  90 ++++++++++++
 lib/commons-core/pom.xml                        |   4 +-
 .../server/api/serializer/ODataSerializer.java  |   5 +-
 .../core/serializer/ODataXmlSerializerImpl.java |   3 +-
 .../serializer/json/ODataJsonSerializer.java    |  30 ++--
 .../tecsvc/processor/TechnicalProcessor.java    |  11 +-
 .../tecsvc/data/JsonDataProviderTest.java       |   8 +-
 .../json/ODataJsonSerializerTest.java           |  25 ++--
 12 files changed, 282 insertions(+), 87 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/lib/commons-api/pom.xml
----------------------------------------------------------------------
diff --git a/lib/commons-api/pom.xml b/lib/commons-api/pom.xml
index ce6849a..6f9768f 100644
--- a/lib/commons-api/pom.xml
+++ b/lib/commons-api/pom.xml
@@ -33,23 +33,27 @@
     <version>0.1.0-SNAPSHOT</version>
     <relativePath>..</relativePath>
   </parent>
-  
+
   <dependencies>
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
     </dependency>
-    
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
     </dependency>    
-    
+
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
     
 </project>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
index 8241457..80e5696 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
@@ -163,11 +163,23 @@ public interface Constants {
   // JSON stuff
   public final static String JSON_METADATA = "odata.metadata";
 
+  public final static String JSON_TYPE = "@odata.type";
+  public final static String JSON_ID = "@odata.id";
+  public final static String JSON_READ_LINK = "@odata.readLink";
+  public final static String JSON_EDIT_LINK = "@odata.editLink";
   public final static String JSON_CONTEXT = "@odata.context";
-
+  public final static String JSON_ETAG = "@odata.etag";
+  public final static String JSON_MEDIA_ETAG = "@odata.mediaEtag";
+  public final static String JSON_MEDIA_CONTENT_TYPE = "@odata.mediaContentType";
+  public final static String JSON_MEDIA_READ_LINK = "@odata.mediaReadLink";
+  public final static String JSON_MEDIA_EDIT_LINK = "@odata.mediaEditLink";
   public final static String JSON_METADATA_ETAG = "@odata.metadataEtag";
-
   public final static String JSON_BIND_LINK_SUFFIX = "@odata.bind";
+  public final static String JSON_ASSOCIATION_LINK = "@odata.associationLink";
+  public final static String JSON_NAVIGATION_LINK = "@odata.navigationLink";
+  public final static String JSON_COUNT = "@odata.count";
+  public final static String JSON_NEXT_LINK = "@odata.nextLink";
+  public final static String JSON_DELTA_LINK = "@odata.deltaLink";
 
   public final static String JSON_NULL = "odata.null";
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/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 8926ceb..2628ebd 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
@@ -22,6 +22,8 @@ import java.net.URI;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
 
 /**
  * High-level representation of a context URL, built from the string value returned by a service; provides access to the
@@ -34,24 +36,31 @@ public class ContextURL {
   private URI uri;
 
   private URI serviceRoot;
-
   private String entitySetOrSingletonOrType;
-
   private String derivedEntity;
-
   private String selectList;
-
   private String navOrPropertyPath;
 
-  private boolean entity;
-
-  private boolean delta;
-
-  private boolean deltaDeletedEntity;
+  public enum Suffix {
+    ENTITY("$entity"),
+    REFERENCE("$ref"),
+    DELTA("$delta"),
+    DELTA_DELETED_ENTITY("$deletedEntity"),
+    DELTA_LINK("$link"),
+    DELTA_DELETED_LINK("$deletedLink");
+
+    private final String representation;
+    private Suffix(final String representation) {
+      this.representation = representation;
+    }
+    public String getRepresentation() {
+      return representation;
+    }
+  }
 
-  private boolean deltaLink;
+  private Suffix suffix;
 
-  private boolean deltaDeletedLink;
+  private ContextURL() {}
 
   public static ContextURL getInstance(final URI contextURL) {
     final ContextURL instance = new ContextURL();
@@ -59,21 +68,31 @@ public class ContextURL {
 
     String contextURLasString = instance.uri.toASCIIString();
 
-    instance.entity = contextURLasString.endsWith("/$entity") || contextURLasString.endsWith("/@Element");
-    contextURLasString = contextURLasString.
-        replace("/$entity", StringUtils.EMPTY).replace("/@Element", StringUtils.EMPTY);
+    if (contextURLasString.endsWith("/$entity") || contextURLasString.endsWith("/@Element")) {
+      instance.suffix = Suffix.ENTITY;
+      contextURLasString = contextURLasString.replace("/$entity", StringUtils.EMPTY)
+          .replace("/@Element", StringUtils.EMPTY);
 
-    instance.delta = contextURLasString.endsWith("/$delta");
-    contextURLasString = contextURLasString.replace("/$delta", StringUtils.EMPTY);
+    } else if (contextURLasString.endsWith("/$ref")) {
+      instance.suffix = Suffix.REFERENCE;
+      contextURLasString = contextURLasString.replace("/$ref", StringUtils.EMPTY);
 
-    instance.deltaDeletedEntity = contextURLasString.endsWith("/$deletedEntity");
-    contextURLasString = contextURLasString.replace("/$deletedEntity", StringUtils.EMPTY);
+    } else if (contextURLasString.endsWith("/$delta")) {
+      instance.suffix = Suffix.DELTA;
+      contextURLasString = contextURLasString.replace("/$delta", StringUtils.EMPTY);
 
-    instance.deltaLink = contextURLasString.endsWith("/$link");
-    contextURLasString = contextURLasString.replace("/$link", StringUtils.EMPTY);
+    } else if (contextURLasString.endsWith("/$deletedEntity")) {
+      instance.suffix = Suffix.DELTA_DELETED_ENTITY;
+      contextURLasString = contextURLasString.replace("/$deletedEntity", StringUtils.EMPTY);
 
-    instance.deltaDeletedLink = contextURLasString.endsWith("/$deletedLink");
-    contextURLasString = contextURLasString.replace("/$deletedLink", 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));
 
@@ -150,23 +169,87 @@ public class ContextURL {
   }
 
   public boolean isEntity() {
-    return entity;
+    return suffix == Suffix.ENTITY;
+  }
+
+  public boolean isReference() {
+    return suffix == Suffix.REFERENCE;
   }
 
   public boolean isDelta() {
-    return delta;
+    return suffix == Suffix.DELTA;
   }
 
   public boolean isDeltaDeletedEntity() {
-    return deltaDeletedEntity;
+    return suffix == Suffix.DELTA_DELETED_ENTITY;
   }
 
   public boolean isDeltaLink() {
-    return deltaLink;
+    return suffix == Suffix.DELTA_LINK;
   }
 
   public boolean isDeltaDeletedLink() {
-    return deltaDeletedLink;
+    return suffix == Suffix.DELTA_DELETED_LINK;
+  }
+
+  public static final class ContextURLBuilder {
+    private ContextURL contextURL = new ContextURL();
+
+    private ContextURLBuilder() {}
+
+    public ContextURLBuilder serviceRoot(final URI serviceRoot) {
+      contextURL.serviceRoot = serviceRoot;
+      return this;
+    }
+
+    public ContextURLBuilder entitySet(final EdmEntitySet entitySet) {
+      contextURL.entitySetOrSingletonOrType = entitySet.getName();
+      return this;
+    }
+
+    public ContextURLBuilder derived(final EdmEntityType derivedType) {
+      contextURL.derivedEntity = derivedType.getFullQualifiedName().getFullQualifiedNameAsString();
+      return this;
+    }
+
+    public ContextURLBuilder suffix(final Suffix suffix) {
+      contextURL.suffix = suffix;
+      return this;
+    }
+
+    public ContextURL build() {
+      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 static final ContextURLBuilder create() {
+    return new ContextURLBuilder();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
index 3b321bc..8624432 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java
@@ -24,6 +24,8 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.olingo.commons.api.Constants;
+
 /**
  * This class is a container for the supported ODataServiceVersions.
  */
@@ -133,20 +135,20 @@ public enum ODataServiceVersion {
     private static final long serialVersionUID = 3109256773218160485L;
 
     {
-      put(JSON_TYPE, "@odata.type");
-      put(JSON_ID, "@odata.id");
-      put(JSON_ETAG, "@odata.etag");
-      put(JSON_READ_LINK, "@odata.readLink");
-      put(JSON_EDIT_LINK, "@odata.editLink");
-      put(JSON_MEDIAREAD_LINK, "@odata.mediaReadLink");
-      put(JSON_MEDIAEDIT_LINK, "@odata.mediaEditLink");
-      put(JSON_MEDIA_CONTENT_TYPE, "@odata.mediaContentType");
-      put(JSON_MEDIA_ETAG, "@odata.mediaEtag");
-      put(JSON_ASSOCIATION_LINK, "@odata.associationLink");
-      put(JSON_NAVIGATION_LINK, "@odata.navigationLink");
-      put(JSON_COUNT, "@odata.count");
-      put(JSON_NEXT_LINK, "@odata.nextLink");
-      put(JSON_DELTA_LINK, "@odata.deltaLink");
+      put(JSON_TYPE, Constants.JSON_TYPE);
+      put(JSON_ID, Constants.JSON_ID);
+      put(JSON_ETAG, Constants.JSON_ETAG);
+      put(JSON_READ_LINK, Constants.JSON_READ_LINK);
+      put(JSON_EDIT_LINK, Constants.JSON_EDIT_LINK);
+      put(JSON_MEDIAREAD_LINK, Constants.JSON_MEDIA_READ_LINK);
+      put(JSON_MEDIAEDIT_LINK, Constants.JSON_MEDIA_EDIT_LINK);
+      put(JSON_MEDIA_CONTENT_TYPE, Constants.JSON_MEDIA_CONTENT_TYPE);
+      put(JSON_MEDIA_ETAG, Constants.JSON_MEDIA_ETAG);
+      put(JSON_ASSOCIATION_LINK, Constants.JSON_ASSOCIATION_LINK);
+      put(JSON_NAVIGATION_LINK, Constants.JSON_NAVIGATION_LINK);
+      put(JSON_COUNT, Constants.JSON_COUNT);
+      put(JSON_NEXT_LINK, Constants.JSON_NEXT_LINK);
+      put(JSON_DELTA_LINK, Constants.JSON_DELTA_LINK);
       put(JSON_ERROR, "error");
     }
   });

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/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
index 84046b2..7575e82 100644
--- 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
@@ -25,7 +25,12 @@ import static org.junit.Assert.assertTrue;
 
 import java.net.URI;
 
+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 ContextURLTest {
 
@@ -202,6 +207,16 @@ public class ContextURLTest {
   }
 
   @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());
@@ -227,4 +242,79 @@ public class ContextURLTest {
     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/b9f4b3c6/lib/commons-core/pom.xml
----------------------------------------------------------------------
diff --git a/lib/commons-core/pom.xml b/lib/commons-core/pom.xml
index 8977822..f2b7e0a 100644
--- a/lib/commons-core/pom.xml
+++ b/lib/commons-core/pom.xml
@@ -65,14 +65,16 @@
       <groupId>com.fasterxml</groupId>
       <artifactId>aalto-xml</artifactId>
     </dependency>
-        
+
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
     </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/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 d1037c5..24e18da 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
@@ -26,7 +26,6 @@ import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.domain.ODataError;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
 
 public interface ODataSerializer {
 
@@ -36,12 +35,12 @@ public interface ODataSerializer {
 
   InputStream metadataDocument(Edm edm);
 
-  InputStream entity(EdmEntityType edmEntityType, Entity entity, ContextURL contextURL);
+  InputStream entity(EdmEntitySet edmEntitySet, Entity entity, ContextURL contextURL);
 
   InputStream entitySet(EdmEntitySet edmEntitySet, EntitySet entitySet, ContextURL contextURL);
 
   /**
-   * Writes an ODataError into an InputStream
+   * Writes an ODataError into an InputStream.
    * @param error the main error
    * @return inputStream containing the OData formatted error
    */

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java
index 2f2afeb..da83808 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java
@@ -31,7 +31,6 @@ import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.domain.ODataError;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
 import org.apache.olingo.server.core.serializer.xml.MetadataDocumentXmlSerializer;
@@ -77,7 +76,7 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
   }
 
   @Override
-  public InputStream entity(final EdmEntityType edmEntityType, final Entity entity, final ContextURL contextURL) {
+  public InputStream entity(final EdmEntitySet edmEntitySet, final Entity entity, final ContextURL contextURL) {
     throw new ODataRuntimeException("Entity serialization not implemented for XML format");
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/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 b2025eb..e1f1992 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
@@ -27,6 +27,7 @@ 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;
@@ -123,24 +124,27 @@ public class ODataJsonSerializer implements ODataSerializer {
   @Override
   public InputStream entitySet(final EdmEntitySet edmEntitySet, final EntitySet entitySet,
       final ContextURL contextURL) {
+    final ContextURL entitySetContextURL = contextURL == null ?
+        ContextURL.create().entitySet(edmEntitySet).build() :
+        contextURL;
     CircleStreamBuffer buffer = new CircleStreamBuffer();
     try {
       JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
       json.writeStartObject();
-      if (contextURL != null && format != ODataFormat.JSON_NO_METADATA) {
-        json.writeStringField(Constants.JSON_CONTEXT, contextURL.getURI().toASCIIString());
+      if (entitySetContextURL != null && format != ODataFormat.JSON_NO_METADATA) {
+        json.writeStringField(Constants.JSON_CONTEXT, entitySetContextURL.getURI().toASCIIString());
       }
       if (entitySet.getCount() != null) {
-        json.writeNumberField("@odata.count", entitySet.getCount());
+        json.writeNumberField(Constants.JSON_COUNT, entitySet.getCount());
       }
       json.writeFieldName(Constants.VALUE);
       json.writeStartArray();
       for (Entity entity : entitySet.getEntities()) {
-        writeEntity(edmEntitySet.getEntityType(), entity, null, json);
+        writeEntity(edmEntitySet, entity, null, json);
       }
       json.writeEndArray();
       if (entitySet.getNext() != null) {
-        json.writeStringField("@odata.nextLink", entitySet.getNext().toASCIIString());
+        json.writeStringField(Constants.JSON_NEXT_LINK, entitySet.getNext().toASCIIString());
       }
       json.close();
     } catch (final IOException e) {
@@ -152,11 +156,14 @@ public class ODataJsonSerializer implements ODataSerializer {
   }
 
   @Override
-  public InputStream entity(final EdmEntityType edmEntityType, final Entity entity, final ContextURL contextURL) {
+  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;
     CircleStreamBuffer buffer = new CircleStreamBuffer();
     try {
       JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
-      writeEntity(edmEntityType, entity, contextURL, json);
+      writeEntity(edmEntitySet, entity, entityContextURL, json);
       json.close();
     } catch (final IOException e) {
       throw new ODataRuntimeException(e);
@@ -166,7 +173,7 @@ public class ODataJsonSerializer implements ODataSerializer {
     return buffer.getInputStream();
   }
 
-  protected void writeEntity(final EdmEntityType entityType, final Entity entity, final ContextURL contextURL,
+  protected void writeEntity(final EdmEntitySet entitySet, final Entity entity, final ContextURL contextURL,
       final JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
     json.writeStartObject();
     if (format != ODataFormat.JSON_NO_METADATA) {
@@ -174,15 +181,16 @@ public class ODataJsonSerializer implements ODataSerializer {
         json.writeStringField(Constants.JSON_CONTEXT, contextURL.getURI().toASCIIString());
       }
       if (entity.getETag() != null) {
-        json.writeStringField("@odata.etag", entity.getETag());
+        json.writeStringField(Constants.JSON_ETAG, entity.getETag());
       }
       if (entity.getMediaETag() != null) {
-        json.writeStringField("@odata.mediaEtag", entity.getMediaETag());
+        json.writeStringField(Constants.JSON_MEDIA_ETAG, entity.getMediaETag());
       }
       if (entity.getMediaContentType() != null) {
-        json.writeStringField("@odata.mediaContentType", entity.getMediaContentType());
+        json.writeStringField(Constants.JSON_MEDIA_CONTENT_TYPE, entity.getMediaContentType());
       }
     }
+    final EdmEntityType entityType = entitySet.getEntityType();
     for (final String propertyName : entityType.getPropertyNames()) {
       final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
       final Property property = entity.getProperty(propertyName);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/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 f9d1e55..2badfab 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
@@ -26,7 +26,6 @@ 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.edm.EdmEntityType;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.commons.api.http.HttpHeader;
@@ -73,8 +72,7 @@ public class TechnicalProcessor implements CollectionProcessor, EntityProcessor
       if (entitySet == null) {
         response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
       } else {
-        response.setContent(serializer.entitySet(edmEntitySet, entitySet,
-            getContextUrl(request, edmEntitySet.getEntityType())));
+        response.setContent(serializer.entitySet(edmEntitySet, entitySet, getContextUrl(edmEntitySet)));
         response.setStatusCode(HttpStatusCode.OK.getStatusCode());
         response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
       }
@@ -97,8 +95,7 @@ public class TechnicalProcessor implements CollectionProcessor, EntityProcessor
       if (entity == null) {
         response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
       } else {
-        response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity,
-            getContextUrl(request, edmEntitySet.getEntityType())));
+        response.setContent(serializer.entity(edmEntitySet, entity, getContextUrl(edmEntitySet)));
         response.setStatusCode(HttpStatusCode.OK.getStatusCode());
         response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
       }
@@ -149,7 +146,7 @@ public class TechnicalProcessor implements CollectionProcessor, EntityProcessor
     return uriResource.getEntitySet();
   }
 
-  private ContextURL getContextUrl(final ODataRequest request, final EdmEntityType entityType) {
-    return ContextURL.getInstance(URI.create(request.getRawBaseUri() + "/" + entityType.getName()));
+  private ContextURL getContextUrl(final EdmEntitySet entitySet) {
+    return ContextURL.create().entitySet(entitySet).build();
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/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
index 462855c..37600f8 100644
--- 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
@@ -65,10 +65,10 @@ public class JsonDataProviderTest {
 
   @Test
   public void doRoundTrip() throws Exception {
-    doRoundTrip(entityContainer.getEntitySet("ESAllPrim"), 1401);
-    doRoundTrip(entityContainer.getEntitySet("ESCompAllPrim"), 1592);
-    doRoundTrip(entityContainer.getEntitySet("ESCollAllPrim"), 2855);
-    doRoundTrip(entityContainer.getEntitySet("ESMixPrimCollComp"), 1032);
+    doRoundTrip(entityContainer.getEntitySet("ESAllPrim"), 1440);
+    doRoundTrip(entityContainer.getEntitySet("ESCompAllPrim"), 1635);
+    doRoundTrip(entityContainer.getEntitySet("ESCollAllPrim"), 2898);
+    doRoundTrip(entityContainer.getEntitySet("ESMixPrimCollComp"), 1079);
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b9f4b3c6/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 d3753b4..3eaba56 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,6 +23,7 @@ import java.net.URI;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.ContextURL.Suffix;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.edm.Edm;
@@ -49,8 +50,8 @@ public class ODataJsonSerializerTest {
   public void entitySimple() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
-    InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
-        ContextURL.getInstance(URI.create("$metadata#ESAllPrim/$entity")));
+    InputStream result = serializer.entity(edmEntitySet, entity,
+        ContextURL.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{"
         + "\"@odata.context\":\"$metadata#ESAllPrim/$entity\","
@@ -80,8 +81,7 @@ public class ODataJsonSerializerTest {
     EntitySet entitySet = data.readAll(edmEntitySet);
     entitySet.setCount(entitySet.getEntities().size());
     entitySet.setNext(URI.create("/next"));
-    InputStream result = serializer.entitySet(edmEntitySet, entitySet,
-        ContextURL.getInstance(URI.create("$metadata#ESAllPrim")));
+    InputStream result = serializer.entitySet(edmEntitySet, entitySet, null);
     final String resultString = IOUtils.toString(result);
 
     Assert.assertTrue(resultString.matches("\\{"
@@ -103,11 +103,12 @@ public class ODataJsonSerializerTest {
   public void entityCollAllPrim() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
-    InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
-        ContextURL.getInstance(URI.create("$metadata#ESCollAllPrim/$entity")));
+    InputStream result = serializer.entity(edmEntitySet, entity,
+        ContextURL.create().serviceRoot(URI.create("http://host/service/"))
+            .entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{"
-        + "\"@odata.context\":\"$metadata#ESCollAllPrim/$entity\","
+        + "\"@odata.context\":\"http://host/service/$metadata#ESCollAllPrim/$entity\","
         + "\"PropertyInt16\":1,"
         + "\"CollPropertyString\":[\"spiderman@comic.com\",\"spidermaus@comic.com\",\"spidergirl@comic.com\"],"
         + "\"CollPropertyBoolean\":[true,false,true],"
@@ -135,8 +136,7 @@ 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.getEntityType(), entity,
-        ContextURL.getInstance(URI.create("$metadata#ESCompAllPrim/$entity")));
+    InputStream result = serializer.entity(edmEntitySet, entity, null);
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{"
         + "\"@odata.context\":\"$metadata#ESCompAllPrim/$entity\","
@@ -166,8 +166,7 @@ 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.getEntityType(), entity,
-        ContextURL.getInstance(URI.create("$metadata#ESMixPrimCollComp/$entity")));
+    InputStream result = serializer.entity(edmEntitySet, entity, null);
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{"
         + "\"@odata.context\":\"$metadata#ESMixPrimCollComp/$entity\","
@@ -186,7 +185,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.getEntityType(), entity, ContextURL.getInstance(URI.create("contextURL")));
+        .entity(edmEntitySet, entity, ContextURL.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"}";
     Assert.assertEquals(expectedResult, resultString);
@@ -197,7 +196,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.getInstance(URI.create("contextURL")));
+        .entitySet(edmEntitySet, entitySet, ContextURL.create().entitySet(edmEntitySet).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{\"value\":["
         + "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"},"