You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/12/03 14:18:01 UTC
[24/35] 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-1626
Commit: 2564a556e353269d4adc58160512ed9d0a5979b4
Parents: e0c970a
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Tue Dec 1 17:37:41 2015 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
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<Integer, String>());
- testMap(new LinkedHashMap());
+ testMap(new LinkedHashMap<Integer, String>());
testMap(new TreeMap<Integer, String>());
testMap(new ConcurrentHashMap8<Integer, String>());
testMap(new ConcurrentHashMap<Integer, String>());
@@ -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<Integer, String> 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<Integer> 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<Integer> implements Externalizable {
+ /** Name. */
+ private String name;
+
+ /**
+ * @param name Name.
+ */
+ public TestQueue(String name) {
+ this.name = name;
+ }
+
+ /** {@inheritDoc} */
+ @NotNull @Override public Iterator<Integer> 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;