You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/12/23 03:56:51 UTC
[13/28] ignite git commit: IGNITE-2213: Fixed serialization of
duplicate fields.
IGNITE-2213: Fixed serialization of duplicate fields.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/627134b2
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/627134b2
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/627134b2
Branch: refs/heads/ignite-gg-10889
Commit: 627134b25ca730d7a7dbcec9facde158c5d15dc3
Parents: d8576b8
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Dec 22 11:28:44 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Dec 22 11:28:44 2015 +0300
----------------------------------------------------------------------
.../internal/binary/BinaryClassDescriptor.java | 56 ++++++++--
.../ignite/internal/binary/BinaryUtils.java | 11 ++
.../binary/BinaryMarshallerSelfTest.java | 110 +++++++++++++++++++
.../IgniteBinaryCacheQueryTestSuite.java | 3 +-
4 files changed, 169 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/627134b2/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index 1eb3882..1105809 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -35,6 +35,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
@@ -44,11 +45,9 @@ import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
-import static java.lang.reflect.Modifier.isStatic;
-import static java.lang.reflect.Modifier.isTransient;
-
/**
* Binary class descriptor.
*/
@@ -250,21 +249,24 @@ public class BinaryClassDescriptor {
BinarySchema.Builder schemaBuilder = BinarySchema.Builder.newBuilder();
+ Set<String> duplicates = duplicateFields(cls);
+
Collection<String> names = new HashSet<>();
Collection<Integer> ids = new HashSet<>();
for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
for (Field f : c.getDeclaredFields()) {
- int mod = f.getModifiers();
-
- if (!isStatic(mod) && !isTransient(mod)) {
+ if (serializeField(f)) {
f.setAccessible(true);
String name = f.getName();
- if (!names.add(name))
- throw new BinaryObjectException("Duplicate field name [fieldName=" + name +
- ", cls=" + cls.getName() + ']');
+ if (duplicates.contains(name))
+ name = BinaryUtils.qualifiedFieldName(c, name);
+
+ boolean added = names.add(name);
+
+ assert added : name;
int fieldId = idMapper.fieldId(typeId, name);
@@ -308,6 +310,42 @@ public class BinaryClassDescriptor {
}
/**
+ * Find all fields with duplicate names in the class.
+ *
+ * @param cls Class.
+ * @return Fields with duplicate names.
+ */
+ private static Set<String> duplicateFields(Class cls) {
+ Set<String> all = new HashSet<>();
+ Set<String> duplicates = new HashSet<>();
+
+ for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
+ for (Field f : c.getDeclaredFields()) {
+ if (serializeField(f)) {
+ String name = f.getName();
+
+ if (!all.add(name))
+ duplicates.add(name);
+ }
+ }
+ }
+
+ return duplicates;
+ }
+
+ /**
+ * Whether the field must be serialized.
+ *
+ * @param f Field.
+ * @return {@code True} if must be serialized.
+ */
+ private static boolean serializeField(Field f) {
+ int mod = f.getModifiers();
+
+ return !Modifier.isStatic(mod) && !Modifier.isTransient(mod);
+ }
+
+ /**
* @return {@code True} if enum.
*/
boolean isEnum() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/627134b2/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 8cb4b38..62a9d26 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
@@ -1883,6 +1883,17 @@ public class BinaryUtils {
}
/**
+ * Create qualified field name.
+ *
+ * @param cls Class.
+ * @param fieldName Field name.
+ * @return Qualified field name.
+ */
+ public static String qualifiedFieldName(Class cls, String fieldName) {
+ return cls.getName() + "." + fieldName;
+ }
+
+ /**
* Enum type.
*/
private static class EnumType {
http://git-wip-us.apache.org/repos/asf/ignite/blob/627134b2/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 fcd511b..ac9771f 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
@@ -54,6 +54,7 @@ import java.util.concurrent.ConcurrentSkipListSet;
import junit.framework.Assert;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.binary.BinaryCollectionFactory;
+import org.apache.ignite.binary.BinaryField;
import org.apache.ignite.binary.BinaryIdMapper;
import org.apache.ignite.binary.BinaryMapFactory;
import org.apache.ignite.binary.BinaryObject;
@@ -63,6 +64,7 @@ import org.apache.ignite.binary.BinaryRawReader;
import org.apache.ignite.binary.BinaryRawWriter;
import org.apache.ignite.binary.BinaryReader;
import org.apache.ignite.binary.BinarySerializer;
+import org.apache.ignite.binary.BinaryType;
import org.apache.ignite.binary.BinaryTypeConfiguration;
import org.apache.ignite.binary.BinaryWriter;
import org.apache.ignite.binary.Binarylizable;
@@ -2315,6 +2317,63 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
}
/**
+ * Test duplicate fields.
+ *
+ * @throws Exception If failed.
+ */
+ public void testDuplicateFields() throws Exception {
+ BinaryMarshaller marsh = binaryMarshaller();
+
+ DuplicateFieldsB obj = new DuplicateFieldsB(1, 2);
+
+ BinaryObjectImpl objBin = marshal(obj, marsh);
+
+ String fieldName = "x";
+ String fieldNameA = DuplicateFieldsA.class.getName() + "." + fieldName;
+ String fieldNameB = DuplicateFieldsB.class.getName() + "." + fieldName;
+
+ // Check "hasField".
+ assert !objBin.hasField(fieldName);
+ assert objBin.hasField(fieldNameA);
+ assert objBin.hasField(fieldNameB);
+
+ // Check direct field access.
+ assertNull(objBin.field(fieldName));
+ assertEquals(1, objBin.field(fieldNameA));
+ assertEquals(2, objBin.field(fieldNameB));
+
+ // Check metadata.
+ BinaryType type = objBin.type();
+
+ Collection<String> fieldNames = type.fieldNames();
+
+ assertEquals(2, fieldNames.size());
+
+ assert !fieldNames.contains(fieldName);
+ assert fieldNames.contains(fieldNameA);
+ assert fieldNames.contains(fieldNameB);
+
+ // Check field access through type.
+ BinaryField field = type.field(fieldName);
+ BinaryField fieldA = type.field(fieldNameA);
+ BinaryField fieldB = type.field(fieldNameB);
+
+ assert !field.exists(objBin);
+ assert fieldA.exists(objBin);
+ assert fieldB.exists(objBin);
+
+ assertNull(field.value(objBin));
+ assertEquals(1, fieldA.value(objBin));
+ assertEquals(2, fieldB.value(objBin));
+
+ // Check object deserialization.
+ DuplicateFieldsB deserialized = objBin.deserialize();
+
+ assertEquals(obj.xA(), deserialized.xA());
+ assertEquals(obj.xB(), deserialized.xB());
+ }
+
+ /**
*
*/
private static interface SomeItf {
@@ -4120,6 +4179,57 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
}
/**
+ * Class B for duplicate fields test.
+ */
+ private static class DuplicateFieldsA {
+ /** Field. */
+ int x;
+
+ /**
+ * Constructor.
+ *
+ * @param x Field.
+ */
+ protected DuplicateFieldsA(int x) {
+ this.x = x;
+ }
+
+ /**
+ * @return A's field.
+ */
+ public int xA() {
+ return x;
+ }
+ }
+
+ /**
+ * Class B for duplicate fields test.
+ */
+ private static class DuplicateFieldsB extends DuplicateFieldsA {
+ /** Field. */
+ int x;
+
+ /**
+ * Constructor.
+ *
+ * @param xA Field for parent class.
+ * @param xB Field for current class.
+ */
+ public DuplicateFieldsB(int xA, int xB) {
+ super(xA);
+
+ this.x = xB;
+ }
+
+ /**
+ * @return B's field.
+ */
+ public int xB() {
+ return x;
+ }
+ }
+
+ /**
*
*/
private static class DecimalReflective {
http://git-wip-us.apache.org/repos/asf/ignite/blob/627134b2/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java
index 1f5d6d1..b145a90 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java
@@ -18,6 +18,7 @@
package org.apache.ignite.testsuites;
import junit.framework.TestSuite;
+import org.apache.ignite.internal.binary.BinaryMarshaller;
import org.apache.ignite.internal.processors.cache.BinarySerializationQuerySelfTest;
import org.apache.ignite.internal.processors.cache.BinarySerializationQueryWithReflectiveSerializerSelfTest;
import org.apache.ignite.internal.processors.cache.CacheLocalQueryMetricsSelfTest;
@@ -32,7 +33,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheQueryIndexingDisable
import org.apache.ignite.internal.processors.cache.GridCacheQueryInternalKeysSelfTest;
import org.apache.ignite.internal.processors.cache.GridCacheQuerySerializationSelfTest;
import org.apache.ignite.internal.processors.cache.GridCacheReduceQueryMultithreadedSelfTest;
-import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectFieldsQuerySelfTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheBinaryObjectsScanSelfTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheCollocatedQuerySelfTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheDuplicateEntityConfigurationSelfTest;
@@ -101,7 +101,6 @@ import org.apache.ignite.internal.processors.query.IgniteSqlSplitterSelfTest;
import org.apache.ignite.internal.processors.query.h2.sql.BaseH2CompareQueryTest;
import org.apache.ignite.internal.processors.query.h2.sql.GridQueryParsingTest;
import org.apache.ignite.internal.processors.query.h2.sql.H2CompareBigQueryTest;
-import org.apache.ignite.internal.binary.BinaryMarshaller;
import org.apache.ignite.spi.communication.tcp.GridOrderedMessageCancelSelfTest;
import org.apache.ignite.testframework.config.GridTestProperties;