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

olingo-odata4 git commit: [OLINGO-795] server support for Enums with implicit values

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 5d364dfa2 -> 587f90433


[OLINGO-795] server support for Enums with implicit values

Change-Id: I1d96eecb108479a654f10426204d4d1e1383bb09

Signed-off-by: Christian Holzer <c....@sap.com>


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

Branch: refs/heads/master
Commit: 587f90433893dadf0d58a1079bdf307681799c47
Parents: 5d364df
Author: Klaus Straubinger <kl...@sap.com>
Authored: Thu Oct 15 09:58:09 2015 +0200
Committer: Christian Holzer <c....@sap.com>
Committed: Thu Oct 15 10:03:42 2015 +0200

----------------------------------------------------------------------
 .../commons/core/edm/EdmEnumTypeImpl.java       |  13 ++-
 .../olingo/commons/core/edm/EdmEnumTest.java    | 115 ++++++++-----------
 .../deserializer/xml/ODataXmlDeserializer.java  |  27 ++---
 .../xml/MetadataDocumentXmlSerializer.java      |   7 +-
 4 files changed, 75 insertions(+), 87 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/587f9043/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java
index 6996ff2..329bf18 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmEnumTypeImpl.java
@@ -92,6 +92,10 @@ public class EdmEnumTypeImpl extends EdmTypeImpl implements EdmEnumType {
     return Collections.unmodifiableList(memberNames);
   }
 
+  /**
+   * Creates the map from member names to member objects,
+   * preserving the order for the case of implicit value assignments.
+   */
   private void createEdmMembers() {
     final Map<String, EdmMember> membersMapLocal = new LinkedHashMap<String, EdmMember>();
     final List<String> memberNamesLocal = new ArrayList<String>();
@@ -132,9 +136,11 @@ public class EdmEnumTypeImpl extends EdmTypeImpl implements EdmEnumType {
     Long result = null;
     for (final String memberValue : value.split(",", isFlags() ? -1 : 1)) {
       Long memberValueLong = null;
+      long count = 0;
       for (final EdmMember member : getMembers()) {
-        if (member.getName().equals(memberValue) || member.getValue().equals(memberValue)) {
-          memberValueLong = Long.decode(member.getValue());
+        count++;
+        if (memberValue.equals(member.getName()) || memberValue.equals(member.getValue())) {
+          memberValueLong = member.getValue() == null ? count - 1 : Long.decode(member.getValue());
         }
       }
       if (memberValueLong == null) {
@@ -172,8 +178,9 @@ public class EdmEnumTypeImpl extends EdmTypeImpl implements EdmEnumType {
     StringBuilder result = new StringBuilder();
 
     final boolean flags = isFlags();
+    long memberValue = -1;
     for (final EdmMember member : getMembers()) {
-      final long memberValue = Long.parseLong(member.getValue());
+      memberValue = member.getValue() == null ? memberValue + 1 : Long.parseLong(member.getValue());
       if (flags) {
         if ((memberValue & remaining) == memberValue) {
           if (result.length() > 0) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/587f9043/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
index 18bb798..7298b0d 100644
--- 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
@@ -71,31 +71,28 @@ public class EdmEnumTest {
         new CsdlEnumType().setName("name").setMembers(memberList).setFlags(false)
             .setUnderlyingType(EdmPrimitiveTypeKind.SByte.getFullQualifiedName()));
 
-    int16EnumType = new EdmEnumTypeImpl(null,
-        new FullQualifiedName("testNamespace", "testName"),
+    final FullQualifiedName testName = new FullQualifiedName("testNamespace", "testName");
+
+    int16EnumType = new EdmEnumTypeImpl(null, 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"))));
+            .setMembers(Arrays.asList(  // implicit values according to specification: 0, 1, 2
+                new CsdlEnumMember().setName("A"),
+                new CsdlEnumMember().setName("B"),
+                new CsdlEnumMember().setName("C"))));
 
-    int32EnumType = new EdmEnumTypeImpl(null,
-        new FullQualifiedName("testNamespace", "testName"),
+    int32EnumType = new EdmEnumTypeImpl(null, 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"))));
+                new CsdlEnumMember().setName("C").setValue("65536"))));
 
-    int32FlagType = new EdmEnumTypeImpl(null,
-        new FullQualifiedName("testNamespace", "testName"),
+    int32FlagType = new EdmEnumTypeImpl(null, 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"),
@@ -127,16 +124,13 @@ public class EdmEnumTest {
   @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());
+    assertEquals(Integer.class, int32FlagType.getUnderlyingType().getDefaultType());
   }
 
   @Test
   public void members() throws Exception {
     assertArrayEquals(new String[] { "first", "second" }, instance.getMemberNames().toArray());
-    assertEquals("64", instance.getMember("second").getValue());
+    assertEquals("64", otherInstance.getMember("second").getValue());
     assertNull(instance.getMember("notExisting"));
   }
 
@@ -146,6 +140,13 @@ public class EdmEnumTest {
   }
 
   @Test
+  public void isFlags() throws Exception {
+    assertTrue(instance.isFlags());
+    assertFalse(nonFlagsInstance.isFlags());
+    assertFalse(int16EnumType.isFlags());
+  }
+
+  @Test
   public void validate() throws Exception {
     assertTrue(instance.validate(null, null, null, null, null, null));
     assertTrue(instance.validate(null, true, null, null, null, null));
@@ -193,7 +194,7 @@ public class EdmEnumTest {
 
     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("C", int32EnumType.valueToString(65536, 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));
@@ -228,11 +229,17 @@ public class EdmEnumTest {
 
     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(65536), int32EnumType.valueOfString("C", null, null, null, null, null,
+        Integer.class));
+
+    expectErrorInValueOfString(int32EnumType, "65536", null, Short.class, "converted");
 
-    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(Short.valueOf((short) 0), int16EnumType.valueOfString("A", null, null, null, null, null,
+        Short.class));
+    assertEquals(Short.valueOf((short) 1), int16EnumType.valueOfString("B", null, null, null, null, null,
+        Short.class));
+    assertEquals(Short.valueOf((short) 2), int16EnumType.valueOfString("C", null, null, null, null, null,
+        Short.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));
@@ -245,47 +252,31 @@ public class EdmEnumTest {
         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) {
+  private void expectErrorInUnderlyingType(final EdmPrimitiveTypeKind underlyingType) {
     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"))));
+              .setUnderlyingType(underlyingType.getFullQualifiedName()));
       fail("Expected exception not thrown");
     } catch (final EdmException e) {
       assertNotNull(e.getLocalizedMessage());
-      assertThat(e.getLocalizedMessage(), containsString(message));
+      assertThat(e.getLocalizedMessage(), containsString("underlying type"));
     }
   }
 
   @Test
   public void unsupportedUnderlyingType() throws Exception {
-    // Test some random unsupported types
-    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.Date, "");
-    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.Geography, "");
-    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.Guid, "");
+    // Test some random unsupported types.
+    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.Date);
+    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.GeographyPoint);
+    expectErrorInUnderlyingType(EdmPrimitiveTypeKind.Guid);
   }
 
   @Test
   public void outOfRangeValueToString() throws Exception {
-    expectErrorInValueToString(int16EnumType, Integer.MAX_VALUE, null, null, null, null, null, "");
+    expectContentErrorInValueToString(int16EnumType, Integer.MAX_VALUE);
   }
 
   protected void expectErrorInFromUriLiteral(final EdmPrimitiveType instance, final String value) {
@@ -298,12 +289,10 @@ public class EdmEnumTest {
     }
   }
 
-  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) {
+  private void expectErrorInValueToString(final EdmPrimitiveType instance, final Object value,
+      final Boolean isNullable, final String message) {
     try {
-      instance.valueToString(value, isNullable, maxLength, precision, scale, isUnicode);
+      instance.valueToString(value, isNullable, null, null, null, null);
       fail("Expected exception not thrown");
     } catch (final EdmPrimitiveTypeException e) {
       assertNotNull(e.getLocalizedMessage());
@@ -312,24 +301,21 @@ public class EdmEnumTest {
   }
 
   protected void expectNullErrorInValueToString(final EdmPrimitiveType instance) {
-    expectErrorInValueToString(instance, null, false, null, null, null, null, "The value NULL is not allowed.");
+    expectErrorInValueToString(instance, null, false, "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");
+    expectErrorInValueToString(instance, value, null, "value type");
   }
 
   protected void expectContentErrorInValueToString(final EdmPrimitiveType instance, final Object value) {
-    expectErrorInValueToString(instance, value, null, null, null, null, null, "' is not valid.");
+    expectErrorInValueToString(instance, value, 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) {
-
+  private void expectErrorInValueOfString(final EdmPrimitiveType instance, final String value,
+      final Boolean isNullable, final Class<?> returnType, final String message) {
     try {
-      instance.valueOfString(value, isNullable, maxLength, precision, scale, isUnicode, returnType);
+      instance.valueOfString(value, isNullable, null, null, null, null, returnType);
       fail("Expected exception not thrown");
     } catch (final EdmPrimitiveTypeException e) {
       assertNotNull(e.getLocalizedMessage());
@@ -338,17 +324,16 @@ public class EdmEnumTest {
   }
 
   protected void expectTypeErrorInValueOfString(final EdmPrimitiveType instance, final String value) {
-    expectErrorInValueOfString(instance, value, null, null, null, null, null, Class.class,
+    expectErrorInValueOfString(instance, value, 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");
+    expectErrorInValueOfString(instance, value, null, instance.getDefaultType(), "illegal content");
   }
 
   protected void expectNullErrorInValueOfString(final EdmPrimitiveType instance) {
-    expectErrorInValueOfString(instance, null, false, null, null, null, null, instance.getDefaultType(),
+    expectErrorInValueOfString(instance, null, false, instance.getDefaultType(),
         "The literal 'null' is not allowed.");
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/587f9043/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 8ff833c..7f34642 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
@@ -54,16 +54,13 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.EdmType;
-import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
-import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
 import org.apache.olingo.commons.core.edm.primitivetype.AbstractGeospatialType;
-import org.apache.olingo.commons.core.edm.primitivetype.SingletonPrimitiveType;
 import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.deserializer.DeserializerException.MessageKeys;
 import org.apache.olingo.server.api.deserializer.DeserializerResult;
 import org.apache.olingo.server.api.deserializer.ODataDeserializer;
-import org.apache.olingo.server.api.deserializer.DeserializerException.MessageKeys;
 import org.apache.olingo.server.core.deserializer.DeserializerResultImpl;
 
 import com.fasterxml.aalto.stax.InputFactoryImpl;
@@ -152,9 +149,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
       final XMLEvent event = reader.nextEvent();
 
       if (event.isStartElement()) {        
-        if (edmType instanceof SingletonPrimitiveType
-            || edmType.getKind() == EdmTypeKind.ENUM
-            || edmType.getKind() == EdmTypeKind.DEFINITION) {
+        if (edmType instanceof EdmPrimitiveType) {
           values.add(primitive(reader, event.asStartElement(), type, isNullable, 
               maxLength, precision, scale, isUnicode));          
         } else if (edmType instanceof EdmComplexType) {
@@ -191,14 +186,14 @@ public class ODataXmlDeserializer implements ODataDeserializer {
   }
 
   private ValueType getValueType(EdmType edmType, boolean isCollection) {
-    if (edmType instanceof SingletonPrimitiveType) {
-      return isCollection? ValueType.COLLECTION_PRIMITIVE:ValueType.PRIMITIVE;
+    if (edmType instanceof EdmPrimitiveType) {
+      if (edmType instanceof EdmEnumType) {
+        return isCollection ? ValueType.COLLECTION_ENUM : ValueType.ENUM;
+      } else {
+        return isCollection ? ValueType.COLLECTION_PRIMITIVE : ValueType.PRIMITIVE;
+      }
     } else if (edmType instanceof EdmComplexType) {
-      return isCollection? ValueType.COLLECTION_COMPLEX:ValueType.COMPLEX;
-    } else if (edmType instanceof EdmEnumType) {
-      return isCollection?ValueType.COLLECTION_ENUM:ValueType.ENUM;
-    } else if (edmType instanceof EdmTypeDefinition) {
-      return isCollection?ValueType.COLLECTION_PRIMITIVE:ValueType.PRIMITIVE;
+      return isCollection ? ValueType.COLLECTION_COMPLEX : ValueType.COMPLEX;
     } else {
       return ValueType.PRIMITIVE;
     }
@@ -227,9 +222,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
     valuable.setType(isCollection ? ("Collection(" + typeName + ")") : typeName);
     if (isCollection) {
       collection(valuable, reader, start, edmType, isNullable, maxLength, precision, scale, isUnicode);
-    } else if (edmType instanceof SingletonPrimitiveType
-        || edmType.getKind() == EdmTypeKind.ENUM
-        || edmType.getKind() == EdmTypeKind.DEFINITION) {
+    } else if (edmType instanceof EdmPrimitiveType) {
       valuable.setValue(getValueType(edmType, false),
           primitive(reader, start, edmType, isNullable, maxLength, precision, scale, isUnicode));          
     } else if (edmType instanceof EdmComplexType) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/587f9043/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
index 81d516b..435fdb7 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
@@ -596,13 +596,16 @@ public class MetadataDocumentXmlSerializer {
     for (EdmEnumType enumType : enumTypes) {
       writer.writeStartElement(XML_ENUM_TYPE);
       writer.writeAttribute(XML_NAME, enumType.getName());
-      writer.writeAttribute(XML_IS_FLAGS, "" + enumType.isFlags());
+      writer.writeAttribute(XML_IS_FLAGS, Boolean.toString(enumType.isFlags()));
       writer.writeAttribute(XML_UNDERLYING_TYPE, getFullQualifiedName(enumType.getUnderlyingType(), false));
 
       for (String memberName : enumType.getMemberNames()) {
         writer.writeEmptyElement(XML_MEMBER);
         writer.writeAttribute(XML_NAME, memberName);
-        writer.writeAttribute(XML_VALUE, enumType.getMember(memberName).getValue());
+        final String value = enumType.getMember(memberName).getValue();
+        if (value != null) {
+          writer.writeAttribute(XML_VALUE, value);
+        }
       }
 
       writer.writeEndElement();