You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2015/12/01 14:08:27 UTC

[14/14] ignite git commit: Ignite-1695 - Fixed reading fields of dynamic type.

Ignite-1695 - Fixed reading fields of dynamic type.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d6bd423a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d6bd423a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d6bd423a

Branch: refs/heads/ignite-1695
Commit: d6bd423aa4438b4f80e88af91e602b7b48150237
Parents: 4bcc431
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Tue Dec 1 16:07:12 2015 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Tue Dec 1 16:07:12 2015 +0300

----------------------------------------------------------------------
 .../internal/portable/BinaryFieldAccessor.java  | 83 +++++++++++++++++---
 .../internal/portable/BinaryReaderExImpl.java   | 11 +++
 .../ignite/internal/util/IgniteUtils.java       |  8 ++
 .../portable/BinaryMarshallerSelfTest.java      | 20 +++++
 4 files changed, 111 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d6bd423a/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/d6bd423a/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/d6bd423a/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/d6bd423a/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 28bc3e5..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
@@ -390,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<Integer, String> e = new GridMapEntry<>(1, "str1");
 
@@ -3752,6 +3764,14 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
     /**
      *
      */
+    public static class SimpleEnclosingObject {
+        /** */
+        private Object simpl;
+    }
+
+    /**
+     *
+     */
     public static class SimpleExternalizable implements Externalizable {
         /** */
         private String field;