Repository: ignite Updated Branches: refs/heads/master fa974286e -> 01f504ff8
IGNITE-5087 Enum comparison fails after marshal-unmarshal with BinaryMarshaller. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/01f504ff Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/01f504ff Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/01f504ff Branch: refs/heads/master Commit: 01f504ff83cc77f80d37981b5c5a15b653861bbd Parents: fa97428 Author: NSAmelchev <[email protected]> Authored: Mon Jul 10 15:03:01 2017 +0300 Committer: Anton Vinogradov <[email protected]> Committed: Mon Jul 10 15:32:15 2017 +0300 ---------------------------------------------------------------------- .../ignite/internal/binary/BinaryUtils.java | 19 +++++- .../internal/binary/BinaryWriterExImpl.java | 4 +- .../binary/builder/BinaryBuilderSerializer.java | 6 +- .../internal/binary/BinaryEnumsSelfTest.java | 71 ++++++++++++++++++++ .../binary/BinaryMarshallerSelfTest.java | 61 +++++++++++++++++ 5 files changed, 154 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/01f504ff/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java index 00b15da..969f3e1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java @@ -590,7 +590,7 @@ public class BinaryUtils { if (type != null) return type; - if (cls.isEnum()) + if (isEnum(cls)) return GridBinaryMarshaller.ENUM; if (cls.isArray()) @@ -1113,7 +1113,7 @@ public class BinaryUtils { return BinaryWriteMode.COL; else if (isSpecialMap(cls)) return BinaryWriteMode.MAP; - else if (cls.isEnum()) + else if (isEnum(cls)) return BinaryWriteMode.ENUM; else if (cls == BinaryEnumObjectImpl.class) return BinaryWriteMode.BINARY_ENUM; @@ -1147,6 +1147,21 @@ public class BinaryUtils { } /** + * Check if class represents a Enum. + * + * @param cls Class. + * @return {@code True} if this is a Enum class. + */ + public static boolean isEnum(Class cls) { + if (cls.isEnum()) + return true; + + Class sCls = cls.getSuperclass(); + + return sCls != null && sCls.isEnum(); + } + + /** * @return Value. */ public static byte[] doReadByteArray(BinaryInputStream in) { http://git-wip-us.apache.org/repos/asf/ignite/blob/01f504ff/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java index f2ba779..a7f645c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java @@ -795,7 +795,7 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje if (val == null) out.writeByte(GridBinaryMarshaller.NULL); else { - BinaryClassDescriptor desc = ctx.descriptorForClass(val.getClass(), false); + BinaryClassDescriptor desc = ctx.descriptorForClass(val.getDeclaringClass(), false); out.unsafeEnsure(1 + 4); @@ -805,7 +805,7 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje out.unsafeWriteInt(desc.typeId()); else { out.unsafeWriteInt(GridBinaryMarshaller.UNREGISTERED_TYPE_ID); - doWriteString(val.getClass().getName()); + doWriteString(val.getDeclaringClass().getName()); } out.writeInt(val.ordinal()); http://git-wip-us.apache.org/repos/asf/ignite/blob/01f504ff/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java index b1a8da9..018444c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java @@ -110,8 +110,8 @@ class BinaryBuilderSerializer { return; } - if (val.getClass().isEnum()) { - String clsName = val.getClass().getName(); + if (BinaryUtils.isEnum(val.getClass())) { + String clsName = ((Enum)val).getDeclaringClass().getName(); int typeId = writer.context().typeId(clsName); String typeName = writer.context().userTypeName(clsName); @@ -128,7 +128,7 @@ class BinaryBuilderSerializer { writer.context().updateMetadata(typeId, meta); // Need register class for marshaller to be able to deserialize enum value. - writer.context().descriptorForClass(val.getClass(), false); + writer.context().descriptorForClass(((Enum)val).getDeclaringClass(), false); writer.writeByte(GridBinaryMarshaller.ENUM); writer.writeInt(typeId); http://git-wip-us.apache.org/repos/asf/ignite/blob/01f504ff/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java index fd26d4a..c18c0ee 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java @@ -539,6 +539,44 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest { } /** + * Test operations on simple type with declared body which is registered in advance. + * + * @throws Exception If failed. + */ + public void testDeclaredBodyEnumRegistered() throws Exception { + checkDeclaredBodyEnum(true); + } + + /** + * Test operations on simple type with declared body which is not registered in advance. + * + * @throws Exception If failed. + */ + public void testDeclaredBodyEnumNotRegistered() throws Exception { + checkDeclaredBodyEnum(false); + } + + /** + * Check enums with declared body. + * + * @param registered Registered flag. + * @throws Exception If failed. + */ + private void checkDeclaredBodyEnum(boolean registered) throws Exception { + startUp(registered); + + cache1.put(1, DeclaredBodyEnum.ONE); + + if (registered) { + assertEquals(DeclaredBodyEnum.ONE, cache1.get(1)); + assertEquals(DeclaredBodyEnum.ONE, cache2.get(1)); + } + + validate((BinaryObject) cacheBinary1.get(1), DeclaredBodyEnum.ONE); + validate((BinaryObject) cacheBinary2.get(1), DeclaredBodyEnum.ONE); + } + + /** * Validate simple array. * * @param registered Registered flag. @@ -606,6 +644,21 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest { if (register) assertEquals(val.name(), obj.enumName()); } + + /** + * Validate single value. + * + * @param obj Binary value. + * @param val Expected value. + */ + private void validate(BinaryObject obj, DeclaredBodyEnum val) { + assertTrue(obj.type().isEnum()); + + assertEquals(node1.binary().typeId(DeclaredBodyEnum.class.getName()), obj.type().typeId()); + assertEquals(node2.binary().typeId(DeclaredBodyEnum.class.getName()), obj.type().typeId()); + + assertEquals(val.ordinal(), obj.enumOrdinal()); + } /** Register enum */ private void defineEnum() { @@ -646,4 +699,22 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest { ONE, TWO } + + /** + * Enumeration for tests. + */ + public enum DeclaredBodyEnum { + ONE { + @Override boolean isSupported() { + return false; + } + }, + TWO { + @Override boolean isSupported() { + return false; + } + }; + + abstract boolean isSupported(); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/01f504ff/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java index a4ace13..926b3c0 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java @@ -649,6 +649,32 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { /** * @throws Exception If failed. */ + public void testDeclaredBodyEnum() throws Exception { + final MarshallerContextTestImpl ctx = new MarshallerContextTestImpl(); + ctx.registerClassName((byte)0, 1, EnumObject.class.getName()); + ctx.registerClassName((byte)0, 2, DeclaredBodyEnum.class.getName()); + + BinaryMarshaller marsh = binaryMarshaller(); + marsh.setContext(ctx); + + EnumObject obj = new EnumObject(1L, "test 1", DeclaredBodyEnum.TWO); + + final byte[] marshal = marsh.marshal(obj); + final Object restored = marsh.unmarshal(marshal, null); + + assertTrue(restored instanceof EnumObject); + + obj = (EnumObject)restored; + + assertEquals(1, obj.id); + assertEquals(DeclaredBodyEnum.TWO.ordinal(), obj.type.ordinal()); + assertEquals(DeclaredBodyEnum.TWO, obj.type); + assertTrue(obj.type == DeclaredBodyEnum.TWO); + } + + /** + * @throws Exception If failed. + */ public void testDateAndTimestampInSingleObject() throws Exception { BinaryTypeConfiguration cfg1 = new BinaryTypeConfiguration(DateClass1.class.getName()); @@ -5456,4 +5482,39 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { val1 = reader.rawReader().readInt(); } } + + /** */ + private static class EnumObject implements Serializable { + /** */ + private long id; + + /** */ + private String name; + + /** */ + private DeclaredBodyEnum type; + + /** */ + EnumObject(final long id, final String name, final DeclaredBodyEnum type) { + this.id = id; + this.name = name; + this.type = type; + } + } + + /** */ + public enum DeclaredBodyEnum { + ONE { + @Override boolean isSupported() { + return false; + } + }, + TWO { + @Override boolean isSupported() { + return false; + } + }; + + abstract boolean isSupported(); + } } \ No newline at end of file
