Return-Path: X-Original-To: apmail-ignite-commits-archive@minotaur.apache.org Delivered-To: apmail-ignite-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 97D2B18FAC for ; Wed, 2 Dec 2015 03:07:34 +0000 (UTC) Received: (qmail 13650 invoked by uid 500); 2 Dec 2015 03:07:34 -0000 Delivered-To: apmail-ignite-commits-archive@ignite.apache.org Received: (qmail 13568 invoked by uid 500); 2 Dec 2015 03:07:34 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 12468 invoked by uid 99); 2 Dec 2015 03:07:31 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Dec 2015 03:07:31 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 4D80EE08B3; Wed, 2 Dec 2015 03:07:31 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: anovikov@apache.org To: commits@ignite.apache.org Date: Wed, 02 Dec 2015 03:07:59 -0000 Message-Id: <2821d8a8badf4045902891ac843b2489@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [30/32] ignite git commit: IGNITE-1695 - Fixed writing polymorphic types. IGNITE-1695 - Fixed writing polymorphic types. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2564a556 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2564a556 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2564a556 Branch: refs/heads/ignite-843-rc2 Commit: 2564a556e353269d4adc58160512ed9d0a5979b4 Parents: e0c970a Author: Alexey Goncharuk Authored: Tue Dec 1 17:37:41 2015 +0300 Committer: Alexey Goncharuk Committed: Tue Dec 1 17:37:41 2015 +0300 ---------------------------------------------------------------------- .../internal/portable/BinaryFieldAccessor.java | 83 +++++++-- .../internal/portable/BinaryReaderExImpl.java | 11 ++ .../ignite/internal/util/IgniteUtils.java | 8 + .../portable/BinaryMarshallerSelfTest.java | 186 ++++++++++++++++--- 4 files changed, 249 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/2564a556/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java index 0eda375..eece245 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.portable; import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.internal.util.GridUnsafe; +import org.apache.ignite.internal.util.typedef.internal.U; import sun.misc.Unsafe; import java.lang.reflect.Field; @@ -74,8 +75,41 @@ public abstract class BinaryFieldAccessor { case P_DOUBLE: return new DoublePrimitiveAccessor(field, id); + case BYTE: + case BOOLEAN: + case SHORT: + case CHAR: + case INT: + case LONG: + case FLOAT: + case DOUBLE: + case DECIMAL: + case STRING: + case UUID: + case DATE: + case TIMESTAMP: + case BYTE_ARR: + case SHORT_ARR: + case INT_ARR: + case LONG_ARR: + case FLOAT_ARR: + case DOUBLE_ARR: + case CHAR_ARR: + case BOOLEAN_ARR: + case DECIMAL_ARR: + case STRING_ARR: + case UUID_ARR: + case DATE_ARR: + case TIMESTAMP_ARR: + case ENUM_ARR: + case OBJECT_ARR: + case PORTABLE_OBJ: + case PORTABLE: + case EXTERNALIZABLE: + return new DefaultFinalClassAccessor(field, id, mode, false); + default: - return new DefaultAccessor(field, id, mode); + return new DefaultFinalClassAccessor(field, id, mode, !U.isFinal(field.getType())); } } @@ -389,10 +423,13 @@ public abstract class BinaryFieldAccessor { /** * Default accessor. */ - private static class DefaultAccessor extends BinaryFieldAccessor { + private static class DefaultFinalClassAccessor extends BinaryFieldAccessor { /** Target field. */ private final Field field; + /** Dynamic accessor flag. */ + private final boolean dynamic; + /** * Constructor. * @@ -400,12 +437,13 @@ public abstract class BinaryFieldAccessor { * @param id Field ID. * @param mode Mode. */ - public DefaultAccessor(Field field, int id, BinaryWriteMode mode) { + DefaultFinalClassAccessor(Field field, int id, BinaryWriteMode mode, boolean dynamic) { super(id, mode); assert field != null; this.field = field; + this.dynamic = dynamic; } /** {@inheritDoc} */ @@ -424,7 +462,7 @@ public abstract class BinaryFieldAccessor { throw new BinaryObjectException("Failed to get value for field: " + field, e); } - switch (mode) { + switch (mode(val)) { case BYTE: writer.writeByteField((Byte) val); @@ -609,6 +647,25 @@ public abstract class BinaryFieldAccessor { /** {@inheritDoc} */ @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException { + Object val = dynamic ? reader.readField(id) : readFixedType(reader); + + try { + if (val != null || !field.getType().isPrimitive()) + field.set(obj, val); + } + catch (IllegalAccessException e) { + throw new BinaryObjectException("Failed to set value for field: " + field, e); + } + } + + /** + * Reads fixed type from the given reader with flags validation. + * + * @param reader Reader to read from. + * @return Read value. + * @throws BinaryObjectException If failed to read value from the stream. + */ + protected Object readFixedType(BinaryReaderExImpl reader) throws BinaryObjectException { Object val = null; switch (mode) { @@ -793,13 +850,17 @@ public abstract class BinaryFieldAccessor { assert false : "Invalid mode: " + mode; } - try { - if (val != null || !field.getType().isPrimitive()) - field.set(obj, val); - } - catch (IllegalAccessException e) { - throw new BinaryObjectException("Failed to set value for field: " + field, e); - } + return val; + } + + /** + * @param val Val to get write mode for. + * @return Write mode. + */ + protected BinaryWriteMode mode(Object val) { + return dynamic ? + val == null ? BinaryWriteMode.OBJECT : PortableUtils.mode(val.getClass()) : + mode; } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/2564a556/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java index b9f851c..ddbf6ba 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java @@ -1628,6 +1628,17 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina } /** + * @return Deserialized object. + * @throws BinaryObjectException If failed. + */ + @Nullable Object readField(int fieldId) throws BinaryObjectException { + if (!findFieldById(fieldId)) + return null; + + return new BinaryReaderExImpl(ctx, in, ldr, hnds).deserialize(); + } + + /** * @param name Field name. * @return Field offset. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/2564a556/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 3dfa9cc..121cd46 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -7667,6 +7667,14 @@ public abstract class IgniteUtils { } /** + * @param cls Class to check. + * @return {@code True} if class is final. + */ + public static boolean isFinal(Class cls) { + return Modifier.isFinal(cls.getModifiers()); + } + + /** * Gets field value. * * @param cls Class. http://git-wip-us.apache.org/repos/asf/ignite/blob/2564a556/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java index cc035f6..49be8dd 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java @@ -21,6 +21,33 @@ import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.InetSocketAddress; +import java.sql.Timestamp; +import java.util.AbstractQueue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Queue; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListSet; import junit.framework.Assert; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.binary.BinaryIdMapper; @@ -47,32 +74,10 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.MarshallerContextTestImpl; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.jetbrains.annotations.NotNull; import org.jsr166.ConcurrentHashMap8; import sun.misc.Unsafe; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.InetSocketAddress; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListSet; - import static org.apache.ignite.internal.portable.streams.PortableMemoryAllocator.INSTANCE; import static org.junit.Assert.assertArrayEquals; @@ -98,7 +103,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { * @throws Exception If failed. */ public void testByte() throws Exception { - assertEquals((byte) 100, marshalUnmarshal((byte) 100).byteValue()); + assertEquals((byte) 100, marshalUnmarshal((byte)100).byteValue()); } /** @@ -126,14 +131,14 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { * @throws Exception If failed. */ public void testFloat() throws Exception { - assertEquals(100.001f, marshalUnmarshal(100.001f).floatValue(), 0); + assertEquals(100.001f, marshalUnmarshal(100.001f), 0); } /** * @throws Exception If failed. */ public void testDouble() throws Exception { - assertEquals(100.001d, marshalUnmarshal(100.001d).doubleValue(), 0); + assertEquals(100.001d, marshalUnmarshal(100.001d), 0); } /** @@ -280,7 +285,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { * @throws Exception If failed. */ public void testDecimalArray() throws Exception { - BigDecimal[] arr = new BigDecimal[] { BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN } ; + BigDecimal[] arr = new BigDecimal[] {BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN} ; assertArrayEquals(arr, marshalUnmarshal(arr)); } @@ -348,7 +353,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { */ public void testMap() throws Exception { testMap(new HashMap()); - testMap(new LinkedHashMap()); + testMap(new LinkedHashMap()); testMap(new TreeMap()); testMap(new ConcurrentHashMap8()); testMap(new ConcurrentHashMap()); @@ -385,6 +390,18 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { /** * @throws Exception If failed. */ + public void testExternalizableInEnclosing() throws Exception { + SimpleEnclosingObject obj = new SimpleEnclosingObject(); + obj.simpl = new SimpleExternalizable("field"); + + SimpleEnclosingObject other = marshalUnmarshal(obj); + + assertEquals(((SimpleExternalizable)obj.simpl).field, ((SimpleExternalizable)other.simpl).field); + } + + /** + * @throws Exception If failed. + */ public void testMapEntry() throws Exception { Map.Entry e = new GridMapEntry<>(1, "str1"); @@ -674,6 +691,111 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { } /** + * @throws Exception If failed. + */ + public void testObjectFieldOfExternalizableCollection() throws Exception { + EnclosingObj obj = new EnclosingObj(); + + obj.queue = new TestQueue("test"); + + assertEquals(obj, marshalUnmarshal(obj)); + } + + /** + * + */ + private static class EnclosingObj implements Serializable { + /** Queue. */ + Queue queue = new TestQueue("test"); + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + EnclosingObj obj = (EnclosingObj)o; + + return Objects.equals(queue, obj.queue); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(queue); + } + } + + /** + * + */ + private static class TestQueue extends AbstractQueue implements Externalizable { + /** Name. */ + private String name; + + /** + * @param name Name. + */ + public TestQueue(String name) { + this.name = name; + } + + /** {@inheritDoc} */ + @NotNull @Override public Iterator iterator() { + return Collections.emptyIterator(); + } + + /** {@inheritDoc} */ + @Override public int size() { + return 0; + } + + /** {@inheritDoc} */ + @Override public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(name); + } + + /** {@inheritDoc} */ + @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + name = (String)in.readObject(); + } + + /** {@inheritDoc} */ + @Override public boolean offer(Integer integer) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public Integer poll() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public Integer peek() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + TestQueue integers = (TestQueue)o; + + return Objects.equals(name, integers.name); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return Objects.hash(name); + } + } + + /** * @param obj Simple object. * @param po Portable object. */ @@ -3642,6 +3764,14 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { /** * */ + public static class SimpleEnclosingObject { + /** */ + private Object simpl; + } + + /** + * + */ public static class SimpleExternalizable implements Externalizable { /** */ private String field;