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

[3/4] olingo-odata4 git commit: [OLINGO-795] server support for Enums and Type Definitions

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d364dfa/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmEnumTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmEnumTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmEnumTest.java
new file mode 100644
index 0000000..18bb798
--- /dev/null
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmEnumTest.java
@@ -0,0 +1,354 @@
+/*
+ * 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.edm;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.EdmEnumType;
+import org.apache.olingo.commons.api.edm.EdmException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
+import org.apache.olingo.commons.api.edm.provider.CsdlEnumMember;
+import org.apache.olingo.commons.api.edm.provider.CsdlEnumType;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+import org.junit.Test;
+
+public class EdmEnumTest {
+
+  private final EdmEnumType instance;
+  private final EdmEnumType otherInstance;
+  private final EdmEnumType nonFlagsInstance;
+  private final EdmEnumType int16EnumType;
+  private final EdmEnumType int32EnumType;
+  private final EdmEnumType int32FlagType;
+
+  public EdmEnumTest() {
+    final List<CsdlEnumMember> memberList = Arrays.asList(
+        new CsdlEnumMember().setName("first").setValue("1"),
+        new CsdlEnumMember().setName("second").setValue("64"));
+
+    final FullQualifiedName enumName = new FullQualifiedName("namespace", "name");
+
+    instance = new EdmEnumTypeImpl(null, enumName,
+        new CsdlEnumType().setName("name").setMembers(memberList).setFlags(true)
+            .setUnderlyingType(EdmPrimitiveTypeKind.SByte.getFullQualifiedName()));
+    
+    otherInstance = new EdmEnumTypeImpl(null, enumName,
+        new CsdlEnumType().setName("name").setMembers(memberList).setFlags(true)
+            .setUnderlyingType(EdmPrimitiveTypeKind.SByte.getFullQualifiedName()));
+
+    nonFlagsInstance = new EdmEnumTypeImpl(null, enumName,
+        new CsdlEnumType().setName("name").setMembers(memberList).setFlags(false)
+            .setUnderlyingType(EdmPrimitiveTypeKind.SByte.getFullQualifiedName()));
+
+    int16EnumType = new EdmEnumTypeImpl(null,
+        new FullQualifiedName("testNamespace", "testName"),
+        new CsdlEnumType().setName("MyEnum")
+            .setFlags(false)
+            .setUnderlyingType(EdmPrimitiveTypeKind.Int16.getFullQualifiedName())
+            .setMembers(Arrays.asList(
+                new CsdlEnumMember().setName("A").setValue("0"),
+                new CsdlEnumMember().setName("B").setValue("1"),
+                new CsdlEnumMember().setName("C").setValue("2"))));
+
+    int32EnumType = new EdmEnumTypeImpl(null,
+        new FullQualifiedName("testNamespace", "testName"),
+        new CsdlEnumType().setName("MyEnum")
+            .setFlags(false)
+            .setUnderlyingType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName())
+            .setMembers(Arrays.asList(
+                new CsdlEnumMember().setName("A").setValue("0"),
+                new CsdlEnumMember().setName("B").setValue("1"),
+                new CsdlEnumMember().setName("C").setValue("2"))));
+
+    int32FlagType = new EdmEnumTypeImpl(null,
+        new FullQualifiedName("testNamespace", "testName"),
+        new CsdlEnumType().setName("MyEnum")
+            .setFlags(true)
+            .setUnderlyingType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName())
+            .setMembers(Arrays.asList(
+                new CsdlEnumMember().setName("A").setValue("2"),
+                new CsdlEnumMember().setName("B").setValue("4"),
+                new CsdlEnumMember().setName("C").setValue("8"))));
+  }
+
+  @Test
+  public void nameSpace() throws Exception {
+    assertEquals("namespace", instance.getNamespace());
+  }
+
+  @Test
+  public void name() throws Exception {
+    assertEquals("name", instance.getName());
+  }
+
+  @Test
+  public void kind() throws Exception {
+    assertEquals(EdmTypeKind.ENUM, instance.getKind());
+  }
+
+  @Test
+  public void compatibility() {
+    assertTrue(instance.isCompatible(instance));
+    assertTrue(instance.isCompatible(otherInstance));
+    assertFalse(instance.isCompatible(instance.getUnderlyingType()));
+  }
+
+  @Test
+  public void defaultType() throws Exception {
+    assertEquals(Byte.class, instance.getDefaultType());
+    EdmEnumType instance = new EdmEnumTypeImpl(null,
+        new FullQualifiedName("testNamespace", "testName"),
+        new CsdlEnumType().setName("MyEnum"));
+    assertEquals(Integer.class, instance.getUnderlyingType().getDefaultType());
+  }
+
+  @Test
+  public void members() throws Exception {
+    assertArrayEquals(new String[] { "first", "second" }, instance.getMemberNames().toArray());
+    assertEquals("64", instance.getMember("second").getValue());
+    assertNull(instance.getMember("notExisting"));
+  }
+
+  @Test
+  public void underlyingType() throws Exception {
+    assertEquals(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.SByte), instance.getUnderlyingType());
+  }
+
+  @Test
+  public void validate() throws Exception {
+    assertTrue(instance.validate(null, null, null, null, null, null));
+    assertTrue(instance.validate(null, true, null, null, null, null));
+    assertFalse(instance.validate(null, false, null, null, null, null));
+    assertFalse(instance.validate("", null, null, null, null, null));
+    assertFalse(instance.validate("something", null, null, null, null, null));
+
+    assertTrue(instance.validate("second", null, null, null, null, null));
+    assertTrue(instance.validate("first,second", null, null, null, null, null));
+    assertTrue(instance.validate("64", null, null, null, null, null));
+    assertTrue(instance.validate("1,64", null, null, null, null, null));
+  }
+
+  @Test
+  public void toUriLiteral() throws Exception {
+    assertNull(instance.toUriLiteral(null));
+    assertEquals("namespace.name'first'", instance.toUriLiteral("first"));
+  }
+
+  @Test
+  public void fromUriLiteral() throws Exception {
+    assertNull(instance.fromUriLiteral(null));
+    assertEquals("first", instance.fromUriLiteral("namespace.name'first'"));
+
+    expectErrorInFromUriLiteral(instance, "");
+    expectErrorInFromUriLiteral(instance, "name'first'");
+    expectErrorInFromUriLiteral(instance, "namespace.name'first");
+    expectErrorInFromUriLiteral(instance, "namespace.namespace'first");
+  }
+
+  @Test
+  public void valueToString() throws Exception {
+    assertNull(instance.valueToString(null, null, null, null, null, null));
+    assertNull(instance.valueToString(null, true, null, null, null, null));
+    assertEquals("first", instance.valueToString(1, null, null, null, null, null));
+    assertEquals("first", instance.valueToString((byte) 1, null, null, null, null, null));
+    assertEquals("first", instance.valueToString((short) 1, null, null, null, null, null));
+    assertEquals("second", instance.valueToString(Integer.valueOf(64), null, null, null, null, null));
+    assertEquals("second", instance.valueToString(64L, null, null, null, null, null));
+    assertEquals("first,second", instance.valueToString(65, null, null, null, null, null));
+
+    expectNullErrorInValueToString(instance);
+    expectContentErrorInValueToString(instance, 3);
+    expectTypeErrorInValueToString(instance, 1.0);
+
+    assertEquals("A", int32EnumType.valueToString(0, false, 0, 0, 0, false));
+    assertEquals("B", int32EnumType.valueToString(1, false, 0, 0, 0, false));
+    assertEquals("C", int32EnumType.valueToString(2, false, 0, 0, 0, false));
+
+    assertEquals("A", int16EnumType.valueToString(0, false, 0, 0, 0, false));
+    assertEquals("B", int16EnumType.valueToString(1, false, 0, 0, 0, false));
+    assertEquals("C", int16EnumType.valueToString(2, false, 0, 0, 0, false));
+
+    assertEquals("A", int32FlagType.valueToString(2, false, 0, 0, 0, false));
+    assertEquals("B", int32FlagType.valueToString(4, false, 0, 0, 0, false));
+    assertEquals("C", int32FlagType.valueToString(8, false, 0, 0, 0, false));
+    assertEquals("A,B", int32FlagType.valueToString(0x2 + 0x4, false, 0, 0, 0, false));
+    assertEquals("B,C", int32FlagType.valueToString(0x4 + 0x8, false, 0, 0, 0, false));
+  }
+
+  @Test
+  public void valueOfString() throws Exception {
+    assertNull(instance.valueOfString(null, null, null, null, null, null, Byte.class));
+    assertNull(instance.valueOfString(null, true, null, null, null, null, Byte.class));
+    assertEquals(Short.valueOf((short) 1), instance.valueOfString("1", null, null, null, null, null, Short.class));
+    assertEquals(Integer.valueOf(1), instance.valueOfString("1", null, null, null, null, null, Integer.class));
+    assertEquals(Long.valueOf(64L), instance.valueOfString("64", null, null, null, null, null, Long.class));
+    assertEquals(Long.valueOf(1), instance.valueOfString("first", null, null, null, null, null, Long.class));
+    assertEquals(Byte.valueOf((byte) 65), instance.valueOfString("first,64", null, null, null, null, null, Byte.class));
+    assertEquals(Integer.valueOf(1), instance.valueOfString("1,1,first", null, null, null, null, null, Integer.class));
+
+    assertEquals(Integer.valueOf(1), nonFlagsInstance.valueOfString("1", null, null, null, null, null, Integer.class));
+    expectContentErrorInValueOfString(nonFlagsInstance, "1,64");
+
+    expectNullErrorInValueOfString(instance);
+    expectContentErrorInValueOfString(instance, "2");
+    expectContentErrorInValueOfString(instance, "1,");
+    expectContentErrorInValueOfString(instance, ",1");
+    expectTypeErrorInValueOfString(instance, "1");
+
+    assertEquals(Integer.valueOf(0), int32EnumType.valueOfString("A", null, null, null, null, null, Integer.class));
+    assertEquals(Integer.valueOf(1), int32EnumType.valueOfString("B", null, null, null, null, null, Integer.class));
+    assertEquals(Integer.valueOf(2), int32EnumType.valueOfString("C", null, null, null, null, null, Integer.class));
+
+    assertEquals(Integer.valueOf(0), int16EnumType.valueOfString("A", null, null, null, null, null, Integer.class));
+    assertEquals(Integer.valueOf(1), int16EnumType.valueOfString("B", null, null, null, null, null, Integer.class));
+    assertEquals(Integer.valueOf(2), int16EnumType.valueOfString("C", null, null, null, null, null, Integer.class));
+
+    assertEquals(Integer.valueOf(2), int32FlagType.valueOfString("A", null, null, null, null, null, Integer.class));
+    assertEquals(Integer.valueOf(4), int32FlagType.valueOfString("B", null, null, null, null, null, Integer.class));
+    assertEquals(Integer.valueOf(8), int32FlagType.valueOfString("C", null, null, null, null, null, Integer.class));
+    assertEquals(Integer.valueOf(0x2 + 0x4), int32FlagType.valueOfString("A,B", null, null, null, null, null,
+        Integer.class));
+    assertEquals(Integer.valueOf(0x4 + 0x8), int32FlagType.valueOfString("B,C", null, null, null, null, null,
+        Integer.class));
+    assertEquals(Integer.valueOf(0x2 + 0x4), int32FlagType.valueOfString("B,A", null, null, null, null, null,
+        Integer.class));
+  }
+
+  private void expectErrorInValueToString(final EdmEnumType instance,
+      final Object value, final Boolean isNullable, final Integer maxLength,
+      final Integer precision, final Integer scale, final Boolean isUnicode,
+      final String message) {
+    try {
+      instance.valueToString(value, isNullable, maxLength, precision, scale, isUnicode);
+      fail("Expected exception not thrown");
+    } catch (final EdmPrimitiveTypeException e) {
+      assertNotNull(e.getLocalizedMessage());
+      assertThat(e.getLocalizedMessage(), containsString(message));
+    }
+  }
+
+  private void expectErrorInUnderlyingType(final EdmPrimitiveTypeKind underlyingType, final String message) {
+    try {
+      new EdmEnumTypeImpl(null,
+          new FullQualifiedName("testNamespace", "testName"),
+          new CsdlEnumType()
+              .setName("MyEnum")
+              .setFlags(false)
+              .setUnderlyingType(underlyingType.getFullQualifiedName())
+              .setMembers(Arrays.asList(
+                  new CsdlEnumMember().setName("A").setValue("0"))));
+      fail("Expected exception not thrown");
+    } catch (final EdmException e) {
+      assertNotNull(e.getLocalizedMessage());
+      assertThat(e.getLocalizedMessage(), containsString(message));
+    }
+  }
+
+  @Test
+  public void unsupportedUnderlyingType() throws Exception {
+    // Test some random unsupported types
+    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.Date, "");
+    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.Geography, "");
+    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.Guid, "");
+  }
+
+  @Test
+  public void outOfRangeValueToString() throws Exception {
+    expectErrorInValueToString(int16EnumType, Integer.MAX_VALUE, null, null, null, null, null, "");
+  }
+
+  protected void expectErrorInFromUriLiteral(final EdmPrimitiveType instance, final String value) {
+    try {
+      instance.fromUriLiteral(value);
+      fail("Expected exception not thrown");
+    } catch (final EdmPrimitiveTypeException e) {
+      assertNotNull(e.getLocalizedMessage());
+      assertThat(e.getLocalizedMessage(), containsString("' has illegal content."));
+    }
+  }
+
+  private void expectErrorInValueToString(final EdmPrimitiveType instance,
+      final Object value, final Boolean isNullable, final Integer maxLength,
+      final Integer precision, final Integer scale, final Boolean isUnicode,
+      final String message) {
+    try {
+      instance.valueToString(value, isNullable, maxLength, precision, scale, isUnicode);
+      fail("Expected exception not thrown");
+    } catch (final EdmPrimitiveTypeException e) {
+      assertNotNull(e.getLocalizedMessage());
+      assertThat(e.getLocalizedMessage(), containsString(message));
+    }
+  }
+
+  protected void expectNullErrorInValueToString(final EdmPrimitiveType instance) {
+    expectErrorInValueToString(instance, null, false, null, null, null, null, "The value NULL is not allowed.");
+  }
+
+  protected void expectTypeErrorInValueToString(final EdmPrimitiveType instance, final Object value) {
+    expectErrorInValueToString(instance, value, null, null, null, null, null, "value type");
+  }
+
+  protected void expectContentErrorInValueToString(final EdmPrimitiveType instance, final Object value) {
+    expectErrorInValueToString(instance, value, null, null, null, null, null, "' is not valid.");
+  }
+
+  private void expectErrorInValueOfString(final EdmPrimitiveType instance,
+      final String value, final Boolean isNullable, final Integer maxLength, final Integer precision,
+      final Integer scale, final Boolean isUnicode, final Class<?> returnType,
+      final String message) {
+
+    try {
+      instance.valueOfString(value, isNullable, maxLength, precision, scale, isUnicode, returnType);
+      fail("Expected exception not thrown");
+    } catch (final EdmPrimitiveTypeException e) {
+      assertNotNull(e.getLocalizedMessage());
+      assertThat(e.getLocalizedMessage(), containsString(message));
+    }
+  }
+
+  protected void expectTypeErrorInValueOfString(final EdmPrimitiveType instance, final String value) {
+    expectErrorInValueOfString(instance, value, null, null, null, null, null, Class.class,
+        "The value type class java.lang.Class is not supported.");
+  }
+
+  protected void expectContentErrorInValueOfString(final EdmPrimitiveType instance, final String value) {
+    expectErrorInValueOfString(instance, value, null, null, null, null, null, instance.getDefaultType(),
+        "illegal content");
+  }
+
+  protected void expectNullErrorInValueOfString(final EdmPrimitiveType instance) {
+    expectErrorInValueOfString(instance, null, false, null, null, null, null, instance.getDefaultType(),
+        "The literal 'null' is not allowed.");
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d364dfa/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmTypeDefinitionTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmTypeDefinitionTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmTypeDefinitionTest.java
new file mode 100644
index 0000000..3d41db4
--- /dev/null
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/EdmTypeDefinitionTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.edm;
+
+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.edm.EdmAnnotationsTarget.TargetType;
+import org.apache.olingo.commons.api.edm.EdmException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
+import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition;
+import org.apache.olingo.commons.core.edm.EdmTypeDefinitionImpl;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
+import org.apache.olingo.commons.core.edm.primitivetype.PrimitiveTypeBaseTest;
+import org.junit.Test;
+
+public class EdmTypeDefinitionTest extends PrimitiveTypeBaseTest {
+
+  private final EdmPrimitiveType instance = new EdmTypeDefinitionImpl(null,
+      new FullQualifiedName("namespace", "def"),
+      new CsdlTypeDefinition().setName("def")
+          .setUnderlyingType(EdmString.getInstance().getFullQualifiedName())
+          .setMaxLength(5)
+          .setUnicode(false));
+
+  @Test
+  public void defaultType() throws Exception {
+    assertEquals(String.class, instance.getDefaultType());
+  }
+
+  @Test
+  public void compatibility() {
+    assertTrue(instance.isCompatible(instance));
+    for (final EdmPrimitiveTypeKind kind : EdmPrimitiveTypeKind.values()) {
+      if (kind != EdmPrimitiveTypeKind.String) {
+        assertFalse(instance.isCompatible(EdmPrimitiveTypeFactory.getInstance(kind)));
+      }
+    }
+  }
+
+  @Test
+  public void toUriLiteral() throws Exception {
+    assertEquals("'Value'", instance.toUriLiteral("Value"));
+  }
+
+  @Test
+  public void fromUriLiteral() throws Exception {
+    assertEquals("Value", instance.fromUriLiteral("'Value'"));
+  }
+
+  @Test
+  public void valueToString() throws Exception {
+    assertEquals("text", instance.valueToString("text", null, null, null, null, null));
+
+    expectFacetsErrorInValueToString(instance, "longtext", null, null, null, null, null);
+    expectFacetsErrorInValueToString(instance, "text", null, 3, null, null, null);
+    expectFacetsErrorInValueToString(instance, "schräg", null, null, null, null, null);
+    expectFacetsErrorInValueToString(instance, "schräg", null, null, null, null, false);
+  }
+
+  @Test
+  public void valueOfString() throws Exception {
+    assertEquals("text", instance.valueOfString("text", null, null, null, null, null, String.class));
+
+    expectFacetsErrorInValueOfString(instance, "longtext", null, null, null, null, null);
+    expectFacetsErrorInValueOfString(instance, "text", null, 3, null, null, null);
+    expectFacetsErrorInValueOfString(instance, "schräg", null, null, null, null, null);
+    expectFacetsErrorInValueOfString(instance, "schräg", null, null, null, null, false);
+
+    expectTypeErrorInValueOfString(instance, "text");
+  }
+
+  @Test
+  public void typeDefOnStringNoFacets() throws Exception {
+    final EdmTypeDefinition typeDef = new EdmTypeDefinitionImpl(null,
+        new FullQualifiedName("namespace", "name"),
+        new CsdlTypeDefinition().setName("typeDef")
+            .setUnderlyingType(EdmString.getInstance().getFullQualifiedName()));
+
+    assertEquals("name", typeDef.getName());
+    assertEquals("namespace", typeDef.getNamespace());
+    assertEquals(new FullQualifiedName("namespace", "name"), typeDef.getFullQualifiedName());
+    assertEquals(String.class, typeDef.getDefaultType());
+    assertEquals(EdmTypeKind.DEFINITION, typeDef.getKind());
+    assertEquals(EdmString.getInstance(), typeDef.getUnderlyingType());
+    assertTrue(typeDef.isCompatible(EdmString.getInstance()));
+    assertEquals(TargetType.TypeDefinition, typeDef.getAnnotationsTargetType());
+    assertEquals(typeDef.getFullQualifiedName(), typeDef.getAnnotationsTargetFQN());
+    assertEquals(typeDef.getName(), typeDef.getAnnotationsTargetPath());
+
+    // String validation
+    assertEquals("'StringValue'", typeDef.toUriLiteral("StringValue"));
+    assertEquals("String''Value", typeDef.fromUriLiteral("'String''''Value'"));
+    assertTrue(typeDef.validate("text", null, null, null, null, null));
+    assertEquals("text", typeDef.valueToString("text", null, null, null, null, null));
+    assertEquals("text", typeDef.valueOfString("text", null, null, null, null, null, String.class));
+
+    // Facets must be initial
+    assertNull(typeDef.getMaxLength());
+    assertNull(typeDef.getPrecision());
+    assertNull(typeDef.getScale());
+    assertNull(typeDef.getSrid());
+    assertTrue(typeDef.isUnicode());
+  }
+
+  @Test(expected = EdmException.class)
+  public void invalidTypeResultsInEdmException() throws Exception {
+    new EdmTypeDefinitionImpl(null,
+        new FullQualifiedName("namespace", "name"),
+        new CsdlTypeDefinition().setName("typeDef")
+            .setUnderlyingType(new FullQualifiedName("wrong", "wrong")))
+        .getUnderlyingType();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d364dfa/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
index 9fb08ab..8ff833c 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
@@ -71,19 +71,16 @@ import com.fasterxml.aalto.stax.InputFactoryImpl;
 public class ODataXmlDeserializer implements ODataDeserializer {
 
   private static final XMLInputFactory FACTORY = new InputFactoryImpl();
-  private static final String ATOM = "a";
-  private static final QName REF_ELEMENT = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_ENTRY_REF);
-  private static final QName PARAMETERS_ELEMENT = new QName(Constants.NS_METADATA, "parameters");
-  private static final QName ID_ATTR = new QName(Constants.NS_ATOM, ATOM);
-
-  private final QName propertiesQName = new QName(Constants.NS_METADATA, Constants.PROPERTIES);
-  private final QName propertyValueQName = new QName(Constants.NS_METADATA, Constants.VALUE);
-  private final QName contextQName = new QName(Constants.NS_METADATA, Constants.CONTEXT);
-  private final QName nullQName = new QName(Constants.NS_METADATA, Constants.ATTR_NULL);
-  private final QName inlineQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_INLINE);
-  private final QName entryRefQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_ENTRY_REF);
-  private final QName etagQName = new QName(Constants.NS_METADATA, Constants.ATOM_ATTR_ETAG); 
-  private final QName countQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_COUNT);
+
+  private static final QName propertiesQName = new QName(Constants.NS_METADATA, Constants.PROPERTIES);
+  private static final QName propertyValueQName = new QName(Constants.NS_METADATA, Constants.VALUE);
+  private static final QName contextQName = new QName(Constants.NS_METADATA, Constants.CONTEXT);
+  private static final QName nullQName = new QName(Constants.NS_METADATA, Constants.ATTR_NULL);
+  private static final QName inlineQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_INLINE);
+  private static final QName entryRefQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_ENTRY_REF);
+  private static final QName etagQName = new QName(Constants.NS_METADATA, Constants.ATOM_ATTR_ETAG);
+  private static final QName countQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_COUNT);
+  private static final QName parametersQName = new QName(Constants.NS_METADATA, "parameters");
 
   protected XMLEventReader getReader(final InputStream input) throws XMLStreamException {
     return FACTORY.createXMLEventReader(input);
@@ -330,7 +327,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
               link.setInlineEntitySet(entitySet(reader, inline, navigationProperty.getType()));
             }
           }
-        } else if (REF_ELEMENT.equals(event.asStartElement().getName())) {
+        } else if (entryRefQName.equals(event.asStartElement().getName())) {
           if (navigationProperty.isCollection()) {
             throw new DeserializerException("Binding annotation: " + link.getTitle() + 
                 " must be collection of entity refercences",
@@ -362,7 +359,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
     while (reader.hasNext() && !foundEndElement) {
       final XMLEvent event = reader.nextEvent();
       
-      if (event.isStartElement() && REF_ELEMENT.equals(event.asStartElement().getName())) {
+      if (event.isStartElement() && entryRefQName.equals(event.asStartElement().getName())) {
           references.add(entityRef(reader, event.asStartElement()));
       }
       
@@ -671,11 +668,8 @@ public class ODataXmlDeserializer implements ODataDeserializer {
         final XMLEvent event = reader.nextEvent();
         if (event.isStartElement()) {
           StartElement start = event.asStartElement();
-          if (REF_ELEMENT.equals(start.getName())) {
-            Attribute context = start.getAttributeByName(ID_ATTR);
-            if (context == null) {
-              context = start.getAttributeByName(new QName("id"));
-            }
+          if (entryRefQName.equals(start.getName())) {
+            Attribute context = start.getAttributeByName(Constants.QNAME_ATOM_ATTR_ID);
             URI uri = URI.create(context.getValue());
             references.add(uri);
           }
@@ -683,8 +677,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
       }
       return DeserializerResultImpl.with().entityReferences(references).build();
     } catch (XMLStreamException e) {
-      throw new DeserializerException("An IOException occurred", e,
-          DeserializerException.MessageKeys.IO_EXCEPTION);
+      throw new DeserializerException(e.getMessage(), e, DeserializerException.MessageKeys.IO_EXCEPTION);
     }
   }
 
@@ -702,7 +695,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
       final XMLEventReader reader = getReader(stream);
       while (reader.hasNext()) {
         final XMLEvent event = reader.nextEvent();
-        if (event.isStartElement() && PARAMETERS_ELEMENT.equals(event.asStartElement().getName())) {
+        if (event.isStartElement() && parametersQName.equals(event.asStartElement().getName())) {
           consumeParameters(edmAction, reader, event.asStartElement(), parameters);
         }        
       }
@@ -765,7 +758,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
           }
         }
         if (!found) {
-          throw new DeserializerException("failed to read "+event.asStartElement().getName().getLocalPart(), 
+          throw new DeserializerException("failed to read " + event.asStartElement().getName().getLocalPart(),
               DeserializerException.MessageKeys.UNKNOWN_CONTENT);          
         }
       }      

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d364dfa/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AbstractODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AbstractODataSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AbstractODataSerializer.java
index c279586..0f0eff6 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AbstractODataSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/AbstractODataSerializer.java
@@ -25,7 +25,7 @@ import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.api.serializer.SerializerException;
 
 public abstract class AbstractODataSerializer implements ODataSerializer {
-  
+
   protected static final String IO_EXCEPTION_TEXT = "An I/O exception occurred.";
 
   protected void closeCircleStreamBufferOutput(OutputStream outputStream, SerializerException cachedException)
@@ -37,11 +37,10 @@ public abstract class AbstractODataSerializer implements ODataSerializer {
         if (cachedException != null) {
           throw cachedException;
         } else {
-          throw new SerializerException("An I/O exception occurred.", e,
+          throw new SerializerException(IO_EXCEPTION_TEXT, e,
               SerializerException.MessageKeys.IO_EXCEPTION);
         }
       }
     }
   }
- 
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d364dfa/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 642a91e..1ddc979 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
@@ -42,7 +42,9 @@ 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.edm.EdmStructuredType;
+import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 import org.apache.olingo.server.api.ODataServerError;
@@ -399,25 +401,25 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
   private void writePropertyValue(final EdmProperty edmProperty,
       final Property property, final Set<List<String>> selectedPaths, final JsonGenerator json)
       throws IOException, SerializerException {
+    final EdmType type = edmProperty.getType();
     try {
-      if (edmProperty.isPrimitive()) {
+      if (edmProperty.isPrimitive()
+          || type.getKind() == EdmTypeKind.ENUM || type.getKind() == EdmTypeKind.DEFINITION) {
         if (edmProperty.isCollection()) {
-          writePrimitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
+          writePrimitiveCollection((EdmPrimitiveType) type, property,
               edmProperty.isNullable(), edmProperty.getMaxLength(),
               edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(), json);
         } else {
-          writePrimitive((EdmPrimitiveType) edmProperty.getType(), property,
+          writePrimitive((EdmPrimitiveType) type, property,
               edmProperty.isNullable(), edmProperty.getMaxLength(),
               edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(), json);
         }
-      } else if (edmProperty.isCollection()) {
-        writeComplexCollection((EdmComplexType) edmProperty.getType(), property, selectedPaths, json);
       } else if (property.isComplex()) {
-        writeComplexValue((EdmComplexType) edmProperty.getType(), property.asComplex().getValue(), selectedPaths, json);
-      } else if (property.isEnum()) {
-        writePrimitive((EdmPrimitiveType) edmProperty.getType(), property,
-            edmProperty.isNullable(), edmProperty.getMaxLength(),
-            edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(), json);
+        if (edmProperty.isCollection()) {
+          writeComplexCollection((EdmComplexType) type, property, selectedPaths, json);
+        } else {
+          writeComplexValue((EdmComplexType) type, property.asComplex().getValue(), selectedPaths, json);
+        }
       } else {
         throw new SerializerException("Property type not yet supported!",
             SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
@@ -437,6 +439,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
     for (Object value : property.asCollection()) {
       switch (property.getValueType()) {
       case COLLECTION_PRIMITIVE:
+      case COLLECTION_ENUM:
         try {
           writePrimitiveValue(type, value, isNullable, maxLength, precision, scale, isUnicode, json);
         } catch (EdmPrimitiveTypeException e) {
@@ -448,9 +451,6 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
       case COLLECTION_GEOSPATIAL:
         throw new SerializerException("Property type not yet supported!",
             SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
-      case COLLECTION_ENUM:
-        json.writeString(value.toString());
-        break;
       default:
         throw new SerializerException("Property type not yet supported!",
             SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d364dfa/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
index 0136df4..2cae476 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
@@ -21,7 +21,6 @@ package org.apache.olingo.server.core.serializer.json;
 import java.io.IOException;
 
 import org.apache.olingo.commons.api.Constants;
-import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmFunctionImport;
@@ -73,48 +72,42 @@ public class ServiceDocumentJsonSerializer {
 
     gen.writeArrayFieldStart(Constants.VALUE);
 
-    final Edm edm = metadata.getEdm();
-    writeEntitySets(gen, edm);
-    writeFunctionImports(gen, edm);
-    writeSingletons(gen, edm);
+    final EdmEntityContainer container = metadata.getEdm().getEntityContainer();
+    writeEntitySets(gen, container);
+    writeFunctionImports(gen, container);
+    writeSingletons(gen, container);
   }
 
-  private void writeEntitySets(final JsonGenerator gen, final Edm edm) throws IOException {
-    EdmEntityContainer container = edm.getEntityContainer(null);
-
+  private void writeEntitySets(final JsonGenerator gen, final EdmEntityContainer container) throws IOException {
     for (EdmEntitySet edmEntitySet : container.getEntitySets()) {
       if (edmEntitySet.isIncludeInServiceDocument()) {
-        gen.writeStartObject();
-        gen.writeObjectField(Constants.JSON_NAME, edmEntitySet.getName());
-        gen.writeObjectField(Constants.JSON_URL, edmEntitySet.getName());
-        gen.writeEndObject();
+        writeElement(gen, null, edmEntitySet.getName(), edmEntitySet.getName());
       }
     }
   }
 
-  private void writeFunctionImports(final JsonGenerator gen, final Edm edm) throws IOException {
-    EdmEntityContainer container = edm.getEntityContainer(null);
-
+  private void writeFunctionImports(final JsonGenerator gen, final EdmEntityContainer container) throws IOException {
     for (EdmFunctionImport edmFunctionImport : container.getFunctionImports()) {
       if (edmFunctionImport.isIncludeInServiceDocument()) {
-        gen.writeStartObject();
-        gen.writeObjectField(Constants.JSON_NAME, edmFunctionImport.getName());
-        gen.writeObjectField(Constants.JSON_URL, edmFunctionImport.getName());
-        gen.writeObjectField(KIND, FUNCTION_IMPORT);
-        gen.writeEndObject();
+        writeElement(gen, FUNCTION_IMPORT, edmFunctionImport.getName(), edmFunctionImport.getName());
       }
     }
   }
 
-  private void writeSingletons(final JsonGenerator gen, final Edm edm) throws IOException {
-    EdmEntityContainer container = edm.getEntityContainer(null);
-
+  private void writeSingletons(final JsonGenerator gen, final EdmEntityContainer container) throws IOException {
     for (EdmSingleton edmSingleton : container.getSingletons()) {
-      gen.writeStartObject();
-      gen.writeObjectField(Constants.JSON_NAME, edmSingleton.getName());
-      gen.writeObjectField(Constants.JSON_URL, edmSingleton.getName());
-      gen.writeObjectField(KIND, SINGLETON);
-      gen.writeEndObject();
+      writeElement(gen, SINGLETON, edmSingleton.getName(), edmSingleton.getName());
+    }
+  }
+
+  private void writeElement(JsonGenerator gen, final String kind, final String reference, final String title)
+      throws IOException {
+    gen.writeStartObject();
+    gen.writeObjectField(Constants.JSON_NAME, title);
+    gen.writeObjectField(Constants.JSON_URL, reference);
+    if (kind != null) {
+      gen.writeObjectField(KIND, kind);
     }
+    gen.writeEndObject();
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d364dfa/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
index 27ba073..3e77239 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
@@ -31,7 +31,6 @@ import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
 import org.apache.olingo.commons.api.Constants;
-import org.apache.olingo.commons.api.ex.ODataErrorDetail;
 import org.apache.olingo.commons.api.data.ComplexValue;
 import org.apache.olingo.commons.api.data.ContextURL;
 import org.apache.olingo.commons.api.data.Entity;
@@ -49,13 +48,14 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
+import org.apache.olingo.commons.api.ex.ODataErrorDetail;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
 import org.apache.olingo.server.api.ODataServerError;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
 import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
 import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
 import org.apache.olingo.server.api.serializer.ReferenceCollectionSerializerOptions;
 import org.apache.olingo.server.api.serializer.ReferenceSerializerOptions;
@@ -72,16 +72,14 @@ import org.apache.olingo.server.core.serializer.utils.ExpandSelectHelper;
 
 public class ODataXmlSerializer extends AbstractODataSerializer {
 
-  private static final String CONTEXT = "context";
   /** The default character set is UTF-8. */
-  public static final String DEFAULT_CHARSET = "UTF-8";
+  public static final String DEFAULT_CHARSET = Constants.UTF8;
   private static final String ATOM = "a";
   private static final String NS_ATOM = Constants.NS_ATOM;
-  private static final String METADATA = "m";
+  private static final String METADATA = Constants.PREFIX_METADATA;
   private static final String NS_METADATA = Constants.NS_METADATA;
-  private static final String DATA = "d";
+  private static final String DATA = Constants.PREFIX_DATASERVICES;
   private static final String NS_DATA = Constants.NS_DATASERVICES;
-  private static final String NS_SCHEMA = Constants.NS_SCHEME;
 
   @Override
   public SerializerResult serviceDocument(final ServiceMetadata metadata, final String serviceRoot)
@@ -155,13 +153,13 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       CircleStreamBuffer buffer = new CircleStreamBuffer();
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
-      writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
+      writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
 
       writer.writeStartElement("error");
       writer.writeDefaultNamespace(NS_METADATA);
       writeErrorDetails(String.valueOf(error.getStatusCode()), error.getMessage(), error.getTarget(), writer);
       if (error.getDetails() != null && !error.getDetails().isEmpty()) {
-        writer.writeStartElement("details");
+        writer.writeStartElement(Constants.ERROR_DETAILS);
         for (ODataErrorDetail inner : error.getDetails()) {
           writeErrorDetails(inner.getCode(), inner.getMessage(), inner.getTarget(), writer);
         }
@@ -191,17 +189,17 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
   private void writeErrorDetails(String code, String message, String target, XMLStreamWriter writer)
       throws XMLStreamException {
     if (code != null) {
-      writer.writeStartElement("code");
-      writer.writeCharacters(String.valueOf(code));
+      writer.writeStartElement(Constants.ERROR_CODE);
+      writer.writeCharacters(code);
       writer.writeEndElement();
     }
 
-    writer.writeStartElement("message");
+    writer.writeStartElement(Constants.ERROR_MESSAGE);
     writer.writeCharacters(message);
     writer.writeEndElement();
 
     if (target != null) {
-      writer.writeStartElement("target");
+      writer.writeStartElement(Constants.ERROR_TARGET);
       writer.writeCharacters(target);
       writer.writeEndElement();
     }
@@ -225,18 +223,18 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       CircleStreamBuffer buffer = new CircleStreamBuffer();
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
-      writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
-      writer.writeStartElement(ATOM, "feed", NS_ATOM);
+      writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
+      writer.writeStartElement(ATOM, Constants.ATOM_ELEM_FEED, NS_ATOM);
       writer.writeNamespace(ATOM, NS_ATOM);
       writer.writeNamespace(METADATA, NS_METADATA);
       writer.writeNamespace(DATA, NS_DATA);
 
-      writer.writeAttribute(METADATA, NS_METADATA, "context",
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
           ContextURLBuilder.create(contextURL).toASCIIString());
       writeMetadataETag(metadata, writer);
 
       if (options != null && options.getId() != null) {
-        writer.writeStartElement(ATOM, "id", NS_ATOM);
+        writer.writeStartElement(ATOM, Constants.ATOM_ELEM_ID, NS_ATOM);
         writer.writeCharacters(options.getId());
         writer.writeEndElement();
       }
@@ -293,7 +291,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       CircleStreamBuffer buffer = new CircleStreamBuffer();
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
-      writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
+      writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
       writeEntity(metadata, entityType, entity, contextURL,
           options == null ? null : options.getExpand(),
           options == null ? null : options.getSelect(), writer, true);
@@ -329,7 +327,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     if (metadata != null
         && metadata.getServiceMetadataETagSupport() != null
         && metadata.getServiceMetadataETagSupport().getMetadataETag() != null) {
-      writer.writeAttribute(METADATA, NS_METADATA, "metadata-etag",
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.ATOM_ATTR_METADATAETAG,
           metadata.getServiceMetadataETagSupport().getMetadataETag());
     }
   }
@@ -347,25 +345,24 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       final SelectOption select, final XMLStreamWriter writer, final boolean top)
           throws XMLStreamException, SerializerException {
 
-    writer.writeStartElement(ATOM, "entry", NS_ATOM);
+    writer.writeStartElement(ATOM, Constants.ATOM_ELEM_ENTRY, NS_ATOM);
     if (top) {
       writer.writeNamespace(ATOM, NS_ATOM);
       writer.writeNamespace(METADATA, NS_METADATA);
       writer.writeNamespace(DATA, NS_DATA);
 
       if (contextURL != null) { // top-level entity
-        writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
             ContextURLBuilder.create(contextURL).toASCIIString());
         writeMetadataETag(metadata, writer);
-
       }
     }
     if (entity.getETag() != null) {
-      writer.writeAttribute(METADATA, NS_METADATA, "etag", entity.getETag());
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.ATOM_ATTR_ETAG, entity.getETag());
     }
 
     if (entity.getId() != null) {
-      writer.writeStartElement(NS_ATOM, "id");
+      writer.writeStartElement(NS_ATOM, Constants.ATOM_ELEM_ID);
       writer.writeCharacters(entity.getId().toASCIIString());
       writer.writeEndElement();
     }
@@ -373,24 +370,21 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     writerAuthorInfo(entity.getTitle(), writer);
 
     if (entity.getId() != null) {
-      writer.writeStartElement(NS_ATOM, "link");
-      writer.writeAttribute("rel", "edit");
-      writer.writeAttribute("href", entity.getId().toASCIIString());
+      writer.writeStartElement(NS_ATOM, Constants.ATOM_ELEM_LINK);
+      writer.writeAttribute(Constants.ATTR_REL, Constants.EDIT_LINK_REL);
+      writer.writeAttribute(Constants.ATTR_HREF, entity.getId().toASCIIString());
       writer.writeEndElement();
     }
 
     if (entityType.hasStream()) {
-      writer.writeStartElement(NS_ATOM, "content");
-      writer.writeAttribute("type", entity.getMediaContentType());
+      writer.writeStartElement(NS_ATOM, Constants.ATOM_ELEM_CONTENT);
+      writer.writeAttribute(Constants.ATTR_TYPE, entity.getMediaContentType());
       if (entity.getMediaContentSource() != null) {
-        writer.writeAttribute("src", entity.getMediaContentSource().toString());
+        writer.writeAttribute(Constants.ATOM_ATTR_SRC, entity.getMediaContentSource().toString());
       } else {
         String id = entity.getId().toASCIIString();
-        if (id.endsWith("/")) {
-          writer.writeAttribute("src", id + "$value");
-        } else {
-          writer.writeAttribute("src", id + "/$value");
-        }
+        writer.writeAttribute(Constants.ATOM_ATTR_SRC,
+            id + (id.endsWith("/") ? "" : "/") + "$value");
       }
       writer.writeEndElement();
     }
@@ -403,18 +397,19 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     EdmEntityType resolvedType = resolveEntityType(metadata, entityType, entity.getType());
     writeNavigationProperties(metadata, resolvedType, entity, expand, writer);
 
-    writer.writeStartElement(ATOM, "category", NS_ATOM);
-    writer.writeAttribute("scheme", NS_SCHEMA);
-    writer.writeAttribute("term", "#" + resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
+    writer.writeStartElement(ATOM, Constants.ATOM_ELEM_CATEGORY, NS_ATOM);
+    writer.writeAttribute(Constants.ATOM_ATTR_SCHEME, Constants.NS_SCHEME);
+    writer.writeAttribute(Constants.ATOM_ATTR_TERM,
+        "#" + resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
     writer.writeEndElement();
 
     // In the case media, content is sibiling
     if (!entityType.hasStream()) {
-      writer.writeStartElement(NS_ATOM, "content");
-      writer.writeAttribute("type", "application/xml");
+      writer.writeStartElement(NS_ATOM, Constants.ATOM_ELEM_CONTENT);
+      writer.writeAttribute(Constants.ATTR_TYPE, "application/xml");
     }
 
-    writer.writeStartElement(METADATA, "properties", NS_METADATA);
+    writer.writeStartElement(METADATA, Constants.PROPERTIES, NS_METADATA);
     writeProperties(metadata, resolvedType, entity.getProperties(), select, writer);
     writer.writeEndElement(); // properties
 
@@ -425,15 +420,15 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
   }
 
   private void writerAuthorInfo(final String title, final XMLStreamWriter writer) throws XMLStreamException {
-    writer.writeStartElement(NS_ATOM, "title");
+    writer.writeStartElement(NS_ATOM, Constants.ATTR_TITLE);
     if (title != null) {
       writer.writeCharacters(title);
     }
     writer.writeEndElement();
-    writer.writeStartElement(NS_ATOM, "summary");
+    writer.writeStartElement(NS_ATOM, Constants.ATOM_ELEM_SUMMARY);
     writer.writeEndElement();
 
-    writer.writeStartElement(NS_ATOM, "updated");
+    writer.writeStartElement(NS_ATOM, Constants.ATOM_ELEM_UPDATED);
     writer.writeCharacters(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
         .format(new Date(System.currentTimeMillis())));
     writer.writeEndElement();
@@ -528,7 +523,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
           }
           if (navigationLink != null) {
             writeLink(writer, navigationLink, false);
-            writer.writeStartElement(METADATA, "inline", NS_METADATA);
+            writer.writeStartElement(METADATA, Constants.ATOM_ELEM_INLINE, NS_METADATA);
             writeExpandedNavigationProperty(metadata, property, navigationLink,
                 innerOptions == null ? null : innerOptions.getExpandOption(),
                 innerOptions == null ? null : innerOptions.getSelectOption(),
@@ -573,16 +568,16 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
 
   private void writeLink(final XMLStreamWriter writer, final Link link, final boolean close)
       throws XMLStreamException {
-    writer.writeStartElement(ATOM, "link", NS_ATOM);
-    writer.writeAttribute("rel", link.getRel());
+    writer.writeStartElement(ATOM, Constants.ATOM_ELEM_LINK, NS_ATOM);
+    writer.writeAttribute(Constants.ATTR_REL, link.getRel());
     if (link.getType() != null) {
-      writer.writeAttribute("type", link.getType());
+      writer.writeAttribute(Constants.ATTR_TYPE, link.getType());
     }
     if (link.getTitle() != null) {
-      writer.writeAttribute("title", link.getTitle());
+      writer.writeAttribute(Constants.ATTR_TITLE, link.getTitle());
     }
     if (link.getHref() != null) {
-      writer.writeAttribute("href", link.getHref());
+      writer.writeAttribute(Constants.ATTR_HREF, link.getHref());
     }
     if (close) {
       writer.writeEndElement();
@@ -595,7 +590,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       throws XMLStreamException, SerializerException {
     if (property.isCollection()) {
       if (navigationLink != null && navigationLink.getInlineEntitySet() != null) {
-        writer.writeStartElement(ATOM, "feed", NS_ATOM);
+        writer.writeStartElement(ATOM, Constants.ATOM_ELEM_FEED, NS_ATOM);
         writeEntitySet(metadata, property.getType(), navigationLink.getInlineEntitySet(), innerExpand,
             innerSelect, writer);
         writer.writeEndElement();
@@ -615,7 +610,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     writer.writeStartElement(DATA, edmProperty.getName(), NS_DATA);
     if (property == null || property.isNull()) {
       if (edmProperty.isNullable()) {
-        writer.writeAttribute(METADATA, NS_METADATA, "null", "true");
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_NULL, "true");
       } else {
         throw new SerializerException("Non-nullable property not present!",
             SerializerException.MessageKeys.MISSING_PROPERTY, edmProperty.getName());
@@ -648,9 +643,14 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       final Property property, final Set<List<String>> selectedPaths,
       final XMLStreamWriter writer) throws XMLStreamException, SerializerException {
     try {
-      if (edmProperty.isPrimitive()) {
+      if (edmProperty.isPrimitive()
+          || edmProperty.getType().getKind() == EdmTypeKind.ENUM
+          || edmProperty.getType().getKind() == EdmTypeKind.DEFINITION) {
         if (edmProperty.isCollection()) {
-          writer.writeAttribute(METADATA, NS_METADATA, "type", "#Collection(" + edmProperty.getType().getName() + ")");
+          writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
+              edmProperty.isPrimitive() ?
+                  "#Collection(" + edmProperty.getType().getName() + ")" :
+                  collectionType(edmProperty.getType()));
           writePrimitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
               edmProperty.isNullable(), edmProperty.getMaxLength(),
               edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
@@ -661,19 +661,16 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
               edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
               writer);
         }
-      } else if (edmProperty.isCollection()) {
-        writer.writeAttribute(METADATA, NS_METADATA, "type", collectionType(edmProperty.getType()));
-        writeComplexCollection(metadata, (EdmComplexType) edmProperty.getType(), property, selectedPaths, writer);
       } else if (property.isComplex()) {
-        writer.writeAttribute(METADATA, NS_METADATA, "type",
-            "#" + complexType(metadata, (EdmComplexType) edmProperty.getType(), property.getType()));
-        writeComplexValue(metadata, (EdmComplexType) edmProperty.getType(), property.asComplex().getValue(),
-            selectedPaths, writer);
-      } else if (property.isEnum()) {
-        writePrimitive((EdmPrimitiveType) edmProperty.getType(), property,
-            edmProperty.isNullable(), edmProperty.getMaxLength(),
-            edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
-            writer);
+        if (edmProperty.isCollection()) {
+          writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE, collectionType(edmProperty.getType()));
+          writeComplexCollection(metadata, (EdmComplexType) edmProperty.getType(), property, selectedPaths, writer);
+        } else {
+          writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
+              "#" + complexType(metadata, (EdmComplexType) edmProperty.getType(), property.getType()));
+          writeComplexValue(metadata, (EdmComplexType) edmProperty.getType(), property.asComplex().getValue(),
+              selectedPaths, writer);
+        }
       } else {
         throw new SerializerException("Property type not yet supported!",
             SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
@@ -690,7 +687,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       final Boolean isUnicode,
       final XMLStreamWriter writer) throws XMLStreamException, EdmPrimitiveTypeException, SerializerException {
     for (Object value : property.asCollection()) {
-      writer.writeStartElement(METADATA, "element", NS_METADATA);
+      writer.writeStartElement(METADATA, Constants.ELEM_ELEMENT, NS_METADATA);
       switch (property.getValueType()) {
       case COLLECTION_PRIMITIVE:
       case COLLECTION_ENUM:
@@ -711,9 +708,9 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       final Property property, final Set<List<String>> selectedPaths, final XMLStreamWriter writer)
       throws XMLStreamException, SerializerException {
     for (Object value : property.asCollection()) {
-      writer.writeStartElement(METADATA, "element", NS_METADATA);
+      writer.writeStartElement(METADATA, Constants.ELEM_ELEMENT, NS_METADATA);
       if (derivedComplexType(type, property.getType()) != null) {
-        writer.writeAttribute(METADATA, NS_METADATA, "type", property.getType());
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE, property.getType());
       }
       switch (property.getValueType()) {
       case COLLECTION_COMPLEX:
@@ -733,7 +730,10 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       throws EdmPrimitiveTypeException, XMLStreamException, SerializerException {
     if (property.isPrimitive()) {
       if (!(type instanceof EdmString)) {
-        writer.writeAttribute(METADATA, NS_METADATA, "type", type.getName());
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
+            type.getKind() == EdmTypeKind.DEFINITION ?
+                "#" + type.getFullQualifiedName().getFullQualifiedNameAsString() :
+                type.getName());
       }
       writePrimitiveValue(type, property.asPrimitive(),
           isNullable, maxLength, precision, scale, isUnicode, writer);
@@ -741,7 +741,8 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       throw new SerializerException("Property type not yet supported!",
           SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
     } else if (property.isEnum()) {
-      writer.writeAttribute(METADATA, NS_METADATA, "type", "#" + type.getName());
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
+          "#" + type.getFullQualifiedName().getFullQualifiedNameAsString());
       writePrimitiveValue(type, property.asEnum(),
           isNullable, maxLength, precision, scale, isUnicode, writer);
     } else {
@@ -757,7 +758,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     final String value = type.valueToString(primitiveValue,
         isNullable, maxLength, precision, scale, isUnicode);
     if (value == null) {
-      writer.writeAttribute(DATA, NS_DATA, "null", "true");
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_NULL, "true");
     } else {
       writer.writeCharacters(value);
     }
@@ -797,16 +798,16 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
 
-      writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
-      writer.writeStartElement(METADATA, "value", NS_METADATA);
+      writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
+      writer.writeStartElement(METADATA, Constants.VALUE, NS_METADATA);
       writer.writeNamespace(METADATA, NS_METADATA);
       if (contextURL != null) {
-        writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
             ContextURLBuilder.create(contextURL).toASCIIString());
       }
       writeMetadataETag(metadata, writer);
       if (property.isNull()) {
-        writer.writeAttribute(METADATA, NS_METADATA, "null", "true");
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_NULL, "true");
       } else {
         writePrimitive(type, property,
             options == null ? null : options.isNullable(),
@@ -853,17 +854,17 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       CircleStreamBuffer buffer = new CircleStreamBuffer();
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
-      writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
-      writer.writeStartElement(METADATA, "value", NS_METADATA);
+      writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
+      writer.writeStartElement(METADATA, Constants.VALUE, NS_METADATA);
       writer.writeNamespace(METADATA, NS_METADATA);
       writer.writeNamespace(DATA, NS_DATA);
-      writer.writeAttribute(METADATA, NS_METADATA, "type", "#"
-          + resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
-      writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
+          "#" + resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
           ContextURLBuilder.create(contextURL).toASCIIString());
       writeMetadataETag(metadata, writer);
       if (property.isNull()) {
-        writer.writeAttribute(METADATA, NS_METADATA, "null", "true");
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_NULL, "true");
       } else {
         final List<Property> values = property.asComplex().getValue();
         writeProperties(metadata, resolvedType, values, options == null ? null : options.getSelect(), writer);
@@ -899,15 +900,15 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
 
-      writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
-      writer.writeStartElement(METADATA, "value", NS_METADATA);
+      writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
+      writer.writeStartElement(METADATA, Constants.VALUE, NS_METADATA);
       writer.writeNamespace(METADATA, NS_METADATA);
       if (contextURL != null) {
-        writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
             ContextURLBuilder.create(contextURL).toASCIIString());
       }
       writeMetadataETag(metadata, writer);
-      writer.writeAttribute(METADATA, NS_METADATA, "type", "#Collection(" + type.getName() + ")");
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE, "#Collection(" + type.getName() + ")");
       writePrimitiveCollection(type, property,
           options == null ? null : options.isNullable(),
           options == null ? null : options.getMaxLength(),
@@ -952,11 +953,11 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
 
-      writer.writeStartElement(METADATA, "value", NS_METADATA);
+      writer.writeStartElement(METADATA, Constants.VALUE, NS_METADATA);
       writer.writeNamespace(METADATA, NS_METADATA);
       writer.writeNamespace(DATA, NS_DATA);
-      writer.writeAttribute(METADATA, NS_METADATA, "type", collectionType(type));
-      writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE, collectionType(type));
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
           ContextURLBuilder.create(contextURL).toASCIIString());
       writeMetadataETag(metadata, writer);
       writeComplexCollection(metadata, type, property, null, writer);
@@ -993,7 +994,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       CircleStreamBuffer buffer = new CircleStreamBuffer();
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
-      writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
+      writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
       writeReference(entity, options == null ? null : options.getContextURL(), writer, true);
       writer.writeEndDocument();
       writer.flush();
@@ -1020,11 +1021,11 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     if (top) {
       writer.writeNamespace(METADATA, NS_METADATA);
       if (contextURL != null) { // top-level entity
-        writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
             ContextURLBuilder.create(contextURL).toASCIIString());
       }
     }
-    writer.writeAttribute("id", entity.getId().toASCIIString());
+    writer.writeAttribute(Constants.ATOM_ATTR_ID, entity.getId().toASCIIString());
     writer.writeEndElement();
   }
 
@@ -1043,13 +1044,13 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       CircleStreamBuffer buffer = new CircleStreamBuffer();
       outputStream = buffer.getOutputStream();
       XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
-      writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
-      writer.writeStartElement(ATOM, "feed", NS_ATOM);
+      writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
+      writer.writeStartElement(ATOM, Constants.ATOM_ELEM_FEED, NS_ATOM);
       writer.writeNamespace(ATOM, NS_ATOM);
       writer.writeNamespace(METADATA, NS_METADATA);
       if (options != null && options.getContextURL() != null) { // top-level entity
-        writer.writeAttribute(METADATA, NS_METADATA, CONTEXT, ContextURLBuilder.create(options.getContextURL())
-            .toASCIIString());
+        writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
+            ContextURLBuilder.create(options.getContextURL()).toASCIIString());
       }
       if (options != null && options.getCount() != null && options.getCount().getValue()
           && entitySet.getCount() != null) {
@@ -1083,16 +1084,16 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
 
   private void writeCount(final EntityCollection entitySet, XMLStreamWriter writer)
       throws XMLStreamException {
-    writer.writeStartElement(METADATA, "count", NS_METADATA);
+    writer.writeStartElement(METADATA, Constants.ATOM_ELEM_COUNT, NS_METADATA);
     writer.writeCharacters(String.valueOf(entitySet.getCount()));
     writer.writeEndElement();
   }
 
   private void writeNextLink(final EntityCollection entitySet, XMLStreamWriter writer)
       throws XMLStreamException {
-    writer.writeStartElement(ATOM, "link", NS_ATOM);
-    writer.writeAttribute("rel", "next");
-    writer.writeAttribute("href", entitySet.getNext().toASCIIString());
+    writer.writeStartElement(ATOM, Constants.ATOM_ELEM_LINK, NS_ATOM);
+    writer.writeAttribute(Constants.ATTR_REL, Constants.NEXT_LINK_REL);
+    writer.writeAttribute(Constants.ATTR_HREF, entitySet.getNext().toASCIIString());
     writer.writeEndElement();
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d364dfa/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ServiceDocumentXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ServiceDocumentXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ServiceDocumentXmlSerializer.java
index b931227..6d130ba 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ServiceDocumentXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ServiceDocumentXmlSerializer.java
@@ -22,7 +22,6 @@ import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
 import org.apache.olingo.commons.api.Constants;
-import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmFunctionImport;
@@ -33,18 +32,12 @@ import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.api.serializer.SerializerException;
 
 public class ServiceDocumentXmlSerializer {
-  public static final String KIND = "kind";
-
-  public static final String FUNCTION_IMPORT = "FunctionImport";
-  public static final String SINGLETON = "Singleton";
-  public static final String SERVICE_DOCUMENT = "ServiceDocument";
-
   private static final String APP = "app";
   private static final String NS_APP = "http://www.w3.org/2007/app";
   private static final String ATOM = "atom";
-  private static final String NS_ATOM = "http://www.w3.org/2005/Atom";
+  private static final String NS_ATOM = Constants.NS_ATOM;
   private static final String METADATA = "metadata";
-  private static final String NS_METADATA = "http://docs.oasis-open.org/odata/ns/metadata";
+  private static final String NS_METADATA = Constants.NS_METADATA;
 
   private final ServiceMetadata metadata;
   private final String serviceRoot;
@@ -69,81 +62,73 @@ public class ServiceDocumentXmlSerializer {
     writer.writeNamespace(ATOM, NS_ATOM);
     writer.writeNamespace(APP, NS_APP);
     writer.writeNamespace(METADATA, NS_METADATA);
-    writer.writeAttribute(METADATA, NS_METADATA, "context", metadataUri);
+    writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT, metadataUri);
 
     if (metadata != null
         && metadata.getServiceMetadataETagSupport() != null
         && metadata.getServiceMetadataETagSupport().getMetadataETag() != null) {
-      writer.writeAttribute(METADATA, NS_METADATA, "metadata-etag",
+      writer.writeAttribute(METADATA, NS_METADATA, Constants.ATOM_ATTR_METADATAETAG,
           metadata.getServiceMetadataETagSupport().getMetadataETag());
     }
 
     writer.writeStartElement(APP, "workspace", NS_APP);
 
-    final Edm edm = metadata.getEdm();
-
-    writer.writeStartElement(ATOM, "title", NS_APP);
-    writer.writeCharacters(edm.getEntityContainer(null).getFullQualifiedName().getFullQualifiedNameAsString());
+    final EdmEntityContainer container = metadata.getEdm().getEntityContainer();
+    writer.writeStartElement(ATOM, Constants.ATOM_ELEM_TITLE, NS_ATOM);
+    writer.writeCharacters(container.getFullQualifiedName().getFullQualifiedNameAsString());
     writer.writeEndElement();
 
-    writeEntitySets(writer, edm);
-    writeFunctionImports(writer, edm);
-    writeSingletons(writer, edm);
+    writeEntitySets(writer, container);
+    writeFunctionImports(writer, container);
+    writeSingletons(writer, container);
     writeServiceDocuments(writer);
     writer.writeEndElement(); // end workspace
     writer.writeEndElement(); // end service
   }
 
   private void writeServiceDocuments(XMLStreamWriter writer) throws XMLStreamException {
-
-    for (EdmxReference reference : this.metadata.getReferences()) {
-      writer.writeStartElement(METADATA, "service-document", NS_METADATA);
-      writer.writeAttribute("href", reference.getUri().toASCIIString());
-      writer.writeStartElement(ATOM, "title", NS_ATOM);
-      writer.writeCharacters(reference.getUri().toASCIIString());
-      writer.writeEndElement();
-      writer.writeEndElement();
+    for (EdmxReference reference : metadata.getReferences()) {
+      final String referenceString = reference.getUri().toASCIIString();
+      writeElement(writer, false, "service-document", referenceString, referenceString);
     }
   }
 
-  private void writeEntitySets(final XMLStreamWriter writer, final Edm edm) throws XMLStreamException {
-    EdmEntityContainer container = edm.getEntityContainer(null);
+  private void writeEntitySets(final XMLStreamWriter writer, final EdmEntityContainer container)
+      throws XMLStreamException {
     for (EdmEntitySet edmEntitySet : container.getEntitySets()) {
       if (edmEntitySet.isIncludeInServiceDocument()) {
-        writer.writeStartElement(APP, "collection", NS_APP);
-        writer.writeAttribute("href", edmEntitySet.getName());
-        writer.writeStartElement(ATOM, "title", NS_ATOM);
-        writer.writeCharacters(edmEntitySet.getName());
-        writer.writeEndElement();
-        writer.writeEndElement();
+        writeElement(writer, true, "collection", edmEntitySet.getName(), edmEntitySet.getName());
       }
     }
   }
 
-  private void writeFunctionImports(final XMLStreamWriter writer, final Edm edm) throws XMLStreamException {
-    EdmEntityContainer container = edm.getEntityContainer(null);
-
+  private void writeFunctionImports(final XMLStreamWriter writer, final EdmEntityContainer container)
+      throws XMLStreamException {
     for (EdmFunctionImport edmFunctionImport : container.getFunctionImports()) {
       if (edmFunctionImport.isIncludeInServiceDocument()) {
-        writer.writeStartElement(METADATA, "function-import", NS_METADATA);
-        writer.writeAttribute("href", edmFunctionImport.getName());
-        writer.writeStartElement(ATOM, "title", NS_ATOM);
-        writer.writeCharacters(edmFunctionImport.getName());
-        writer.writeEndElement();
-        writer.writeEndElement();
+        writeElement(writer, false, "function-import", edmFunctionImport.getName(), edmFunctionImport.getName());
       }
     }
   }
 
-  private void writeSingletons(final XMLStreamWriter writer, final Edm edm) throws XMLStreamException {
-    EdmEntityContainer container = edm.getEntityContainer(null);
+  private void writeSingletons(final XMLStreamWriter writer, final EdmEntityContainer container)
+      throws XMLStreamException {
     for (EdmSingleton edmSingleton : container.getSingletons()) {
-      writer.writeStartElement(METADATA, "singleton", NS_METADATA);
-      writer.writeAttribute("href", edmSingleton.getName());
-      writer.writeStartElement(ATOM, "title", NS_ATOM);
-      writer.writeCharacters(edmSingleton.getName());
-      writer.writeEndElement();
-      writer.writeEndElement();
+      writeElement(writer, false, "singleton", edmSingleton.getName(), edmSingleton.getName());
     }
   }
+
+  private void writeElement(XMLStreamWriter writer, final boolean isApp, final String kind, final String reference,
+      final String title) throws XMLStreamException {
+    if (isApp) {
+      writer.writeStartElement(APP, kind, NS_APP);
+    } else {
+      writer.writeStartElement(METADATA, kind, NS_METADATA);
+    }
+    writer.writeAttribute(Constants.ATTR_HREF, reference);
+    writer.writeStartElement(ATOM, Constants.ATOM_ELEM_TITLE, NS_ATOM);
+    writer.writeCharacters(title);
+    writer.writeEndElement();
+    writer.writeEndElement();
+  }
 }