You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@olingo.apache.org by Frédéric SOUCHU <Fr...@ingenico.com> on 2015/04/17 18:15:19 UTC

[OData4.0] Enum serialization bug - fix proposal under way

There is a bug in the way enumerated values are serialized when values are overlapping.
This type:
return new EnumType()
              .setName("CarType")
              .setFlags(false)
              .setUnderlyingType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName())
              .setMembers(
                     Arrays.asList(
new EnumMember()
                     .setName("NotProvided")
                     .setValue("0"),
new EnumMember()
.setName("SuperCar")
.setValue("1"),
new EnumMember()
.setName("MonsterCar")
.setValue("2"),
new EnumMember()
.setName("SpaceCar")
.setValue("3"),
new EnumMember()
.setName("SlowCar")
.setValue("4")));

With values set as:
entitySet.getEntities().add(new Entity()
.addProperty(createPrimitive("Id", 1))
...
.addProperty(new PropertyImpl(CarsEdmProvider.ETN_CARTYPE.getFullQualifiedNameAsString(), "Type", ValueType.ENUM, rnd.nextInt(5))));

Will produce the following incorrect output (using the Cars sample):
{
Id: 1
Model: "F1 W03"
ModelYear: "2012"
Price: 189189.43
Currency: "EUR"
Type: "NotProvided,SlowCar" // it should be a single value...
}

Looking at the code, it seems the Enum has always been thought as a list of exclusive binary values :[
I'll propose a fix (see the yellow parts) and *test* early next week (on top of creating a bug!).
       protected String constructEnumValue(final long value)
                     throws EdmPrimitiveTypeException {
              long remaining = value;
              StringBuilder result = new StringBuilder();

              for (final EdmMember member : getMembers()) {
                     if (isFlags()) {
                            final long memberValue = Long.parseLong(member.getValue());
                            if ((memberValue & remaining) == memberValue) {
                                   if (result.length() > 0) {
                                          result.append(',');
                                   }
                                   result.append(member.getName());
                                   remaining ^= memberValue;
                            }
                     } else {
                            final long memberValue =  Long.parseLong(member.getValue());
                            if (value == memberValue) {
                                   return member.getName();
                            }
                     }
              }

              if (remaining != 0) {
                     throw new EdmPrimitiveTypeException("The value '" + value
                                   + "' is not valid.");
              }
              return result.toString();
       }

Regards,
Frederic