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/20 11:35:13 UTC
[OData 4.0 Server] Created enum serialization bug + fix + unit
tests proposal
I created:
https://issues.apache.org/jira/browse/OLINGO-633
+ spent it a bit of time creating a unit test & fix (see attached).
Can an official Olingo contributor review my fix proposal and commit it in master branch?
Cheers,
Frederic
From: Frédéric SOUCHU
Sent: 17 April 2015 18:15
To: user@olingo.apache.org
Subject: [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
Re: [OData 4.0 Server] Created enum serialization bug + fix + unit
tests proposal
Posted by "Bolz, Michael" <mi...@sap.com>.
Hi Frederic,
I will take a look into your contribution.
Best regards,
Michael
> On 20 Apr 2015, at 11:35, Frédéric SOUCHU <Fr...@ingenico.com> wrote:
>
> I created:
> https://issues.apache.org/jira/browse/OLINGO-633 <https://issues.apache.org/jira/browse/OLINGO-633>
>
> + spent it a bit of time creating a unit test & fix (see attached).
>
> Can an official Olingo contributor review my fix proposal and commit it in master branch?
>
> Cheers,
> Frederic
>
> From: Frédéric SOUCHU
> Sent: 17 April 2015 18:15
> To: user@olingo.apache.org <ma...@olingo.apache.org>
> Subject: [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
> <EmdEnumTest.java><EdmEnumTypeImpl.java>