From 88ece6ef1545228d14a9b2d674abc24ed567fdb6 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 6 Sep 2017 04:06:33 +0900 Subject: [PATCH 01/72] generate getters and setters for primitive list --- .../io/realm/processor/ClassMetaData.java | 80 ++++--- .../io/realm/processor/RealmProcessor.java | 6 +- .../processor/RealmProxyClassGenerator.java | 136 ++++++++--- .../java/io/realm/processor/TypeMirrors.java | 65 ++++++ .../main/java/io/realm/processor/Utils.java | 32 +++ .../java/io/realm/entities/AllJavaTypes.java | 103 ++++++++ .../java/io/realm/entities/NullTypes.java | 221 ++++++++++++++++++ 7 files changed, 585 insertions(+), 58 deletions(-) create mode 100644 realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java index 92a819fea2..34456085a5 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -58,6 +57,7 @@ public class ClassMetaData { private final List indexedFields = new ArrayList(); // list of all fields marked @Index. private final Set backlinks = new HashSet(); private final Set nullableFields = new HashSet(); // Set of fields which can be nullable + private final Set nullableValueListFields = new HashSet(); // Set of fields whose elements can be nullable private String packageName; // package name for model class. private boolean hasDefaultConstructor; // True if model has a public no-arg constructor. @@ -71,30 +71,32 @@ public class ClassMetaData { private final Types typeUtils; private final Elements elements; - public ClassMetaData(ProcessingEnvironment env, TypeElement clazz) { + public ClassMetaData(ProcessingEnvironment env, TypeMirrors typeMirrors, TypeElement clazz) { this.classType = clazz; this.className = clazz.getSimpleName().toString(); typeUtils = env.getTypeUtils(); elements = env.getElementUtils(); - TypeMirror stringType = elements.getTypeElement("java.lang.String").asType(); + + validPrimaryKeyTypes = Arrays.asList( - stringType, - typeUtils.getPrimitiveType(TypeKind.SHORT), - typeUtils.getPrimitiveType(TypeKind.INT), - typeUtils.getPrimitiveType(TypeKind.LONG), - typeUtils.getPrimitiveType(TypeKind.BYTE) + typeMirrors.STRING_MIRROR, + typeMirrors.PRIMITIVE_LONG_MIRROR, + typeMirrors.PRIMITIVE_INT_MIRROR, + typeMirrors.PRIMITIVE_SHORT_MIRROR, + typeMirrors.PRIMITIVE_BYTE_MIRROR ); + validListValueTypes = Arrays.asList( - stringType, - typeUtils.getArrayType(typeUtils.getPrimitiveType(TypeKind.BYTE)), - elements.getTypeElement(Boolean.class.getName()).asType(), - elements.getTypeElement(Long.class.getName()).asType(), - elements.getTypeElement(Integer.class.getName()).asType(), - elements.getTypeElement(Short.class.getName()).asType(), - elements.getTypeElement(Byte.class.getName()).asType(), - elements.getTypeElement(Double.class.getName()).asType(), - elements.getTypeElement(Float.class.getName()).asType(), - elements.getTypeElement(Date.class.getName()).asType() + typeMirrors.STRING_MIRROR, + typeMirrors.BINARY_MIRROR, + typeMirrors.BOOLEAN_MIRROR, + typeMirrors.LONG_MIRROR, + typeMirrors.INTEGER_MIRROR, + typeMirrors.SHORT_MIRROR, + typeMirrors.BYTE_MIRROR, + typeMirrors.DOUBLE_MIRROR, + typeMirrors.FLOAT_MIRROR, + typeMirrors.DATE_MIRROR ); for (Element element : classType.getEnclosedElements()) { @@ -181,6 +183,15 @@ public boolean isNullable(VariableElement variableElement) { return nullableFields.contains(variableElement); } + /** + * Checks if the element of RealmList designated by {@code realmListVariableElement} is nullable. + * + * @return {@code true} if the element is nullable type, {@code false} otherwise. + */ + public boolean isElementNullable(VariableElement realmListVariableElement) { + return nullableValueListFields.contains(realmListVariableElement); + } + /** * Checks if a VariableElement is indexed. * @@ -448,15 +459,26 @@ private boolean categorizeField(Element element) { if (!categorizeIndexField(element, field)) { return false; } } - if (isRequiredField(field)) { - categorizeRequiredField(element, field); + // @Required annotation of RealmList field only affects its value type, not field itself. + if (Utils.isRealmList(field)) { + // We only check @Required annotation. @org.jetbrains.annotations.NotNull annotation should not affect nullability of the list values. + if (!hasRequiredAnnotation(field)) { + final TypeMirror elementTypeMirror = ((DeclaredType) field.asType()).getTypeArguments().get(0); + if (!Utils.isRealmModel(elementTypeMirror)) { + nullableValueListFields.add(field); + } + } } else { - // The field doesn't have the @Required annotation. - // Without @Required annotation, boxed types/RealmObject/Date/String/bytes should be added to - // nullableFields. - // RealmList and Primitive types are NOT nullable always. @Required annotation is not supported. - if (!Utils.isPrimitiveType(field) && !Utils.isRealmList(field)) { - nullableFields.add(field); + if (isRequiredField(field)) { + categorizeRequiredField(element, field); + } else { + // The field doesn't have the @Required and @org.jetbrains.annotations.NotNull annotation. + // Without @Required annotation, boxed types/RealmObject/Date/String/bytes should be added to + // nullableFields. + // RealmList and Primitive types are NOT nullable always. @Required annotation is not supported. + if (!Utils.isPrimitiveType(field)) { + nullableFields.add(field); + } } } @@ -481,8 +503,12 @@ private boolean categorizeField(Element element) { return true; } + private boolean hasRequiredAnnotation(VariableElement field) { + return field.getAnnotation(Required.class) != null; + } + private boolean isRequiredField(VariableElement field) { - if (field.getAnnotation(Required.class) != null) { + if (hasRequiredAnnotation(field)) { return true; } diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProcessor.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProcessor.java index ef75e16923..758a5ce031 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProcessor.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProcessor.java @@ -172,6 +172,8 @@ public boolean process(Set annotations, RoundEnvironment // Create all proxy classes private boolean processAnnotations(RoundEnvironment roundEnv) { + final TypeMirrors typeMirrors = new TypeMirrors(processingEnv); + for (Element classElement : roundEnv.getElementsAnnotatedWith(RealmClass.class)) { // The class must either extend RealmObject or implement RealmModel @@ -186,7 +188,7 @@ private boolean processAnnotations(RoundEnvironment roundEnv) { return false; } - ClassMetaData metadata = new ClassMetaData(processingEnv, (TypeElement) classElement); + ClassMetaData metadata = new ClassMetaData(processingEnv, typeMirrors, (TypeElement) classElement); if (!metadata.isModelClass()) { continue; } Utils.note("Processing class " + metadata.getSimpleClassName()); @@ -202,7 +204,7 @@ private boolean processAnnotations(RoundEnvironment roundEnv) { Utils.error(e.getMessage(), classElement); } - RealmProxyClassGenerator sourceCodeGenerator = new RealmProxyClassGenerator(processingEnv, metadata); + RealmProxyClassGenerator sourceCodeGenerator = new RealmProxyClassGenerator(processingEnv, typeMirrors, metadata); try { sourceCodeGenerator.generate(); } catch (IOException e) { diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 7f0dc16c92..d1b40f30eb 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -32,6 +32,7 @@ import javax.lang.model.element.Modifier; import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Types; import javax.tools.JavaFileObject; @@ -76,6 +77,7 @@ public class RealmProxyClassGenerator { } private final ProcessingEnvironment processingEnvironment; + private final TypeMirrors typeMirrors; private final ClassMetaData metadata; private final String simpleClassName; private final String qualifiedClassName; @@ -83,8 +85,9 @@ public class RealmProxyClassGenerator { private final String qualifiedGeneratedClassName; private final boolean suppressWarnings; - public RealmProxyClassGenerator(ProcessingEnvironment processingEnvironment, ClassMetaData metadata) { + public RealmProxyClassGenerator(ProcessingEnvironment processingEnvironment, TypeMirrors typeMirrors, ClassMetaData metadata) { this.processingEnvironment = processingEnvironment; + this.typeMirrors = typeMirrors; this.metadata = metadata; this.simpleClassName = metadata.getSimpleClassName(); this.qualifiedClassName = metadata.getFullyQualifiedClassName(); @@ -312,7 +315,8 @@ private void emitPersistedFieldAccessors(final JavaWriter writer) throws IOExcep } else if (Utils.isRealmModel(field)) { emitRealmModel(writer, field, fieldName, fieldTypeCanonicalName); } else if (Utils.isRealmList(field)) { - emitRealmList(writer, field, fieldName, fieldTypeCanonicalName); + final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + emitRealmList(writer, field, fieldName, fieldTypeCanonicalName, elementTypeMirror); } else { throw new UnsupportedOperationException(String.format(Locale.US, "Field \"%s\" of type \"%s\" is not supported.", fieldName, fieldTypeCanonicalName)); @@ -508,8 +512,10 @@ private void emitRealmList( JavaWriter writer, final VariableElement field, String fieldName, - String fieldTypeCanonicalName) throws IOException { - String genericType = Utils.getGenericTypeQualifiedName(field); + String fieldTypeCanonicalName, + final TypeMirror elementTypeMirror) throws IOException { + final String genericType = Utils.getGenericTypeQualifiedName(field); + final boolean forRealmModel = Utils.isRealmModel(elementTypeMirror); // Getter writer.emitAnnotation("Override"); @@ -538,12 +544,17 @@ public void emit(JavaWriter writer) throws IOException { field.getSimpleName().toString()) .emitStatement("return") .endControlFlow(); - final String modelFqcn = Utils.getGenericTypeQualifiedName(field); - writer.beginControlFlow("if (value != null && !value.isManaged())") + + if (!forRealmModel) { + return; + } + + writer.emitSingleLineComment("if the list contains unmanaged RealmObjects, convert them to managed.") + .beginControlFlow("if (value != null && !value.isManaged())") .emitStatement("final Realm realm = (Realm) proxyState.getRealm$realm()") - .emitStatement("final RealmList<%1$s> original = value", modelFqcn) - .emitStatement("value = new RealmList<%1$s>()", modelFqcn) - .beginControlFlow("for (%1$s item : original)", modelFqcn) + .emitStatement("final RealmList<%1$s> original = value", genericType) + .emitStatement("value = new RealmList<%1$s>()", genericType) + .beginControlFlow("for (%1$s item : original)", genericType) .beginControlFlow("if (item == null || RealmObject.isManaged(item))") .emitStatement("value.add(item)") .nextControlFlow("else") @@ -560,20 +571,61 @@ public void emit(JavaWriter writer) throws IOException { .emitStatement("osList.removeAll()") .beginControlFlow("if (value == null)") .emitStatement("return") - .endControlFlow() - .beginControlFlow("for (RealmModel linkedObject : (RealmList) value)") - .beginControlFlow("if (!(RealmObject.isManaged(linkedObject) && RealmObject.isValid(linkedObject)))") - .emitStatement("throw new IllegalArgumentException(\"Each element of 'value' must be a valid managed object.\")") - .endControlFlow() - .beginControlFlow("if (((RealmObjectProxy) linkedObject).realmGet$proxyState().getRealm$realm() != proxyState.getRealm$realm())") - .emitStatement("throw new IllegalArgumentException(\"Each element of 'value' must belong to the same Realm.\")") - .endControlFlow() - .emitStatement("osList.addRow(((RealmObjectProxy) linkedObject).realmGet$proxyState().getRow$realm().getIndex())") - .endControlFlow() - .endMethod(); + .endControlFlow(); + + if (forRealmModel) { + writer.beginControlFlow("for (RealmModel linkedObject : value)") + .beginControlFlow("if (!(RealmObject.isManaged(linkedObject) && RealmObject.isValid(linkedObject)))") + .emitStatement("throw new IllegalArgumentException(\"Each element of 'value' must be a valid managed object.\")") + .endControlFlow() + .beginControlFlow("if (((RealmObjectProxy) linkedObject).realmGet$proxyState().getRealm$realm() != proxyState.getRealm$realm())") + .emitStatement("throw new IllegalArgumentException(\"Each element of 'value' must belong to the same Realm.\")") + .endControlFlow() + .emitStatement("osList.addRow(((RealmObjectProxy) linkedObject).realmGet$proxyState().getRow$realm().getIndex())") + .endControlFlow(); + } else { + writer.beginControlFlow("for (%1$s item : value)", genericType) + .beginControlFlow("if (item == null)") + .emitStatement(metadata.isElementNullable(field) ? "osList.addNull()" : "throw new IllegalArgumentException(\"Storing 'null' into " + fieldName + "' is not allowed by schema.\")") + .nextControlFlow("else") + .emitStatement(getStatementForAppendingValueToOsList("osList", "item", elementTypeMirror)) + .endControlFlow() + .endControlFlow(); + } + writer.endMethod(); + } //@formatter:on + private String getStatementForAppendingValueToOsList( + @SuppressWarnings("SameParameterValue") String osListVariableName, + @SuppressWarnings("SameParameterValue") String valueVariableName, + TypeMirror elementTypeMirror) { + if (elementTypeMirror == typeMirrors.STRING_MIRROR) { + return osListVariableName + ".addString(" + valueVariableName + ")"; + } + if (elementTypeMirror == typeMirrors.LONG_MIRROR || elementTypeMirror == typeMirrors.INTEGER_MIRROR + || elementTypeMirror == typeMirrors.SHORT_MIRROR || elementTypeMirror == typeMirrors.BYTE_MIRROR) { + return osListVariableName + ".addLong(" + valueVariableName + ".longValue())"; + } + if (elementTypeMirror.equals(typeMirrors.BINARY_MIRROR)) { + return osListVariableName + ".addBinary(" + valueVariableName + ")"; + } + if (elementTypeMirror == typeMirrors.DATE_MIRROR) { + return osListVariableName + ".addDate(" + valueVariableName + ")"; + } + if (elementTypeMirror == typeMirrors.BOOLEAN_MIRROR) { + return osListVariableName + ".addBoolean(" + valueVariableName + ")"; + } + if (elementTypeMirror == typeMirrors.DOUBLE_MIRROR) { + return osListVariableName + ".addDouble(" + valueVariableName + ".doubleValue())"; + } + if (elementTypeMirror == typeMirrors.FLOAT_MIRROR) { + return osListVariableName + ".addFloat(" + valueVariableName + ".floatValue())"; + } + throw new RuntimeException("unexpected element type: " + elementTypeMirror.toString()); + } + private interface CodeEmitter { void emit(JavaWriter writer) throws IOException; } @@ -1003,7 +1055,7 @@ private void emitInsertMethod(JavaWriter writer) throws IOException { .endControlFlow() .emitStatement("Table.nativeSetLink(tableNativePtr, columnInfo.%1$sIndex, rowIndex, cache%1$s, false)", fieldName) .endControlFlow(); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); writer .emitEmptyLine() @@ -1019,6 +1071,8 @@ private void emitInsertMethod(JavaWriter writer) throws IOException { .emitStatement("%1$sOsList.addRow(cacheItemIndex%1$s)", fieldName) .endControlFlow() .endControlFlow(); + } else if (Utils.isRealmValueList(field)) { + // FIXME need to implement logic for value list fields. } else { if (metadata.getPrimaryKey() != field) { @@ -1083,7 +1137,7 @@ private void emitInsertListMethod(JavaWriter writer) throws IOException { .endControlFlow() .emitStatement("table.setLink(columnInfo.%1$sIndex, rowIndex, cache%1$s, false)", fieldName) .endControlFlow(); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); writer .emitEmptyLine() @@ -1100,6 +1154,9 @@ private void emitInsertListMethod(JavaWriter writer) throws IOException { .endControlFlow() .endControlFlow(); + } else if (Utils.isRealmValueList(field)) { + // FIXME need to implement logic for value list fields. + } else { if (metadata.getPrimaryKey() != field) { setTableValues(writer, fieldType, fieldName, interfaceName, getter, false); @@ -1159,7 +1216,7 @@ private void emitInsertOrUpdateMethod(JavaWriter writer) throws IOException { // No need to throw exception here if the field is not nullable. A exception will be thrown in setter. .emitStatement("Table.nativeNullifyLink(tableNativePtr, columnInfo.%sIndex, rowIndex)", fieldName) .endControlFlow(); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); writer .emitEmptyLine() @@ -1178,6 +1235,9 @@ private void emitInsertOrUpdateMethod(JavaWriter writer) throws IOException { .endControlFlow() .emitEmptyLine(); + } else if (Utils.isRealmValueList(field)) { + // FIXME need to implement logic for value list fields. + } else { if (metadata.getPrimaryKey() != field) { setTableValues(writer, fieldType, fieldName, interfaceName, getter, true); @@ -1243,7 +1303,7 @@ private void emitInsertOrUpdateListMethod(JavaWriter writer) throws IOException // No need to throw exception here if the field is not nullable. A exception will be thrown in setter. .emitStatement("Table.nativeNullifyLink(tableNativePtr, columnInfo.%sIndex, rowIndex)", fieldName) .endControlFlow(); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); writer .emitEmptyLine() @@ -1262,6 +1322,9 @@ private void emitInsertOrUpdateListMethod(JavaWriter writer) throws IOException .endControlFlow() .emitEmptyLine(); + } else if (Utils.isRealmValueList(field)) { + // FIXME need to implement logic for value list fields. + } else { if (metadata.getPrimaryKey() != field) { setTableValues(writer, fieldType, fieldName, interfaceName, getter, true); @@ -1393,7 +1456,7 @@ private void emitCopyMethod(JavaWriter writer) throws IOException { .endControlFlow() // No need to throw exception here if the field is not nullable. A exception will be thrown in setter. .endControlFlow(); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); writer.emitEmptyLine() .emitStatement("RealmList<%s> %sList = realmObjectSource.%s()", genericType, fieldName, getter) @@ -1415,6 +1478,9 @@ private void emitCopyMethod(JavaWriter writer) throws IOException { .endControlFlow() .emitEmptyLine(); + } else if (Utils.isRealmModelList(field)) { + // FIXME need to implement logic for value list fields. + } else if (Utils.isMutableRealmInteger(field)) { writer.emitEmptyLine() .emitStatement("realmObjectCopy.%1$s().set(realmObjectSource.%1$s().get())", getter); @@ -1469,7 +1535,7 @@ private void emitCreateDetachedCopyMethod(JavaWriter writer) throws IOException .emitSingleLineComment("Deep copy of %s", fieldName) .emitStatement("unmanagedCopy.%s(%s.createDetachedCopy(realmSource.%s(), currentDepth + 1, maxDepth, cache))", setter, Utils.getProxyClassSimpleName(field), getter); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { writer .emitEmptyLine() .emitSingleLineComment("Deep copy of %s", fieldName) @@ -1488,6 +1554,9 @@ private void emitCreateDetachedCopyMethod(JavaWriter writer) throws IOException .emitStatement("unmanaged%sList.add(item)", fieldName) .endControlFlow() .endControlFlow(); + } else if (Utils.isRealmValueList(field)) { + // FIXME need to implement logic for value list fields. + } else if (Utils.isMutableRealmInteger(field)) { // If the user initializes the unmanaged MutableRealmInteger to null, this will fail mysteriously. writer.emitStatement("unmanagedCopy.%s().set(realmSource.%s().get())", getter, getter); @@ -1539,7 +1608,7 @@ private void emitUpdateMethod(JavaWriter writer) throws IOException { .endControlFlow() // No need to throw exception here if the field is not nullable. A exception will be thrown in setter. .endControlFlow(); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); writer .emitStatement("RealmList<%s> %sList = realmObjectSource.%s()", genericType, fieldName, getter) @@ -1559,6 +1628,9 @@ private void emitUpdateMethod(JavaWriter writer) throws IOException { .endControlFlow() .endControlFlow(); + } else if (Utils.isRealmValueList(field)) { + // FIXME need to implement logic for value list fields. + } else if (Utils.isMutableRealmInteger(field)) { writer.emitStatement("realmObjectTarget.%s().set(realmObjectSource.%s().get())", getter, getter); } else { @@ -1774,7 +1846,7 @@ private void emitCreateOrUpdateUsingJsonObject(JavaWriter writer) throws IOExcep writer ); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { RealmJsonTypeHelper.emitFillRealmListWithJsonValue( "objProxy", metadata.getInternalGetter(fieldName), @@ -1784,6 +1856,9 @@ private void emitCreateOrUpdateUsingJsonObject(JavaWriter writer) throws IOExcep Utils.getProxyClassSimpleName(field), writer); + } else if (Utils.isRealmValueList(field)) { + // FIXME need to implement logic for value list fields. + } else if (Utils.isMutableRealmInteger(field)) { RealmJsonTypeHelper.emitFillJavaTypeWithJsonValue( "objProxy", @@ -1856,7 +1931,7 @@ private void emitCreateUsingJsonStream(JavaWriter writer) throws IOException { writer ); - } else if (Utils.isRealmList(field)) { + } else if (Utils.isRealmModelList(field)) { RealmJsonTypeHelper.emitFillRealmListFromStream( "objProxy", metadata.getInternalGetter(fieldName), @@ -1865,6 +1940,9 @@ private void emitCreateUsingJsonStream(JavaWriter writer) throws IOException { Utils.getProxyClassSimpleName(field), writer); + } else if (Utils.isRealmValueList(field)) { + // FIXME need to implement logic for value list fields. + } else if (Utils.isMutableRealmInteger(field)) { RealmJsonTypeHelper.emitFillJavaTypeFromStream( "objProxy", diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java new file mode 100644 index 0000000000..b3652b8cdb --- /dev/null +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java @@ -0,0 +1,65 @@ +/* + * Copyright 2017 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.processor; + +import java.util.Date; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; + + +public class TypeMirrors { + public final TypeMirror STRING_MIRROR; + public final TypeMirror BINARY_MIRROR; + public final TypeMirror BOOLEAN_MIRROR; + public final TypeMirror LONG_MIRROR; + public final TypeMirror INTEGER_MIRROR; + public final TypeMirror SHORT_MIRROR; + public final TypeMirror BYTE_MIRROR; + public final TypeMirror DOUBLE_MIRROR; + public final TypeMirror FLOAT_MIRROR; + public final TypeMirror DATE_MIRROR; + + public final TypeMirror PRIMITIVE_LONG_MIRROR; + public final TypeMirror PRIMITIVE_INT_MIRROR; + public final TypeMirror PRIMITIVE_SHORT_MIRROR; + public final TypeMirror PRIMITIVE_BYTE_MIRROR; + + public TypeMirrors(ProcessingEnvironment env) { + final Types typeUtils = env.getTypeUtils(); + final Elements elementUtils = env.getElementUtils(); + + STRING_MIRROR = elementUtils.getTypeElement("java.lang.String").asType(); + BINARY_MIRROR = typeUtils.getArrayType(typeUtils.getPrimitiveType(TypeKind.BYTE)); + BOOLEAN_MIRROR = elementUtils.getTypeElement(Boolean.class.getName()).asType(); + LONG_MIRROR = elementUtils.getTypeElement(Long.class.getName()).asType(); + INTEGER_MIRROR = elementUtils.getTypeElement(Integer.class.getName()).asType(); + SHORT_MIRROR = elementUtils.getTypeElement(Short.class.getName()).asType(); + BYTE_MIRROR = elementUtils.getTypeElement(Byte.class.getName()).asType(); + DOUBLE_MIRROR = elementUtils.getTypeElement(Double.class.getName()).asType(); + FLOAT_MIRROR = elementUtils.getTypeElement(Float.class.getName()).asType(); + DATE_MIRROR = elementUtils.getTypeElement(Date.class.getName()).asType(); + + PRIMITIVE_LONG_MIRROR = typeUtils.getPrimitiveType(TypeKind.LONG); + PRIMITIVE_INT_MIRROR = typeUtils.getPrimitiveType(TypeKind.INT); + PRIMITIVE_SHORT_MIRROR = typeUtils.getPrimitiveType(TypeKind.SHORT); + PRIMITIVE_BYTE_MIRROR = typeUtils.getPrimitiveType(TypeKind.BYTE); + } +} diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java index a0da41abe4..844e74f3d2 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java @@ -164,6 +164,38 @@ public static boolean isRealmList(VariableElement field) { return typeUtils.isAssignable(field.asType(), realmList); } + /** + * @return the {@link TypeMirror} of the elements in {@code RealmList}. + */ + public static TypeMirror getRealmListElementTypeMirror(VariableElement field) { + if (!isRealmList(field)) { + return null; + } + return ((DeclaredType) field.asType()).getTypeArguments().get(0); + } + + /** + * @return {@code true} if a given field type is {@code RealmList} and its value type is Realm Object, {@code false} otherwise. + */ + public static boolean isRealmModelList(VariableElement field) { + final TypeMirror elementTypeMirror = getRealmListElementTypeMirror(field); + if (elementTypeMirror == null) { + return false; + } + return isRealmModel(elementTypeMirror); + } + + /** + * @return {@code true} if a given field type is {@code RealmList} and its value type is Realm Object, {@code false} otherwise. + */ + public static boolean isRealmValueList(VariableElement field) { + final TypeMirror elementTypeMirror = getRealmListElementTypeMirror(field); + if (elementTypeMirror == null) { + return false; + } + return !isRealmModel(elementTypeMirror); + } + /** * @return {@code true} if a given field type is {@code RealmModel}, {@code false} otherwise. */ diff --git a/realm/realm-library/src/androidTest/java/io/realm/entities/AllJavaTypes.java b/realm/realm-library/src/androidTest/java/io/realm/entities/AllJavaTypes.java index 22e509c956..8a85897b55 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/entities/AllJavaTypes.java +++ b/realm/realm-library/src/androidTest/java/io/realm/entities/AllJavaTypes.java @@ -45,6 +45,18 @@ public class AllJavaTypes extends RealmObject { public static final String FIELD_BINARY = "fieldBinary"; public static final String FIELD_OBJECT = "fieldObject"; public static final String FIELD_LIST = "fieldList"; + + public static final String FIELD_STRING_LIST = "fieldStringList"; + public static final String FIELD_BINARY_LIST = "fieldBinaryList"; + public static final String FIELD_BOOLEAN_LIST = "fieldBooleanList"; + public static final String FIELD_LONG_LIST = "fieldLongList"; + public static final String FIELD_INTEGER_LIST = "fieldIntegerList"; + public static final String FIELD_SHORT_LIST = "fieldShortList"; + public static final String FIELD_BYTE_LIST = "fieldByteList"; + public static final String FIELD_DOUBLE_LIST = "fieldDoubleList"; + public static final String FIELD_FLOAT_LIST = "fieldFloatList"; + public static final String FIELD_DATE_LIST = "fieldDateList"; + public static final String FIELD_LO_OBJECT = "objectParents"; public static final String FIELD_LO_LIST = "listParents"; @@ -77,6 +89,17 @@ public class AllJavaTypes extends RealmObject { private AllJavaTypes fieldObject; private RealmList fieldList; + private RealmList fieldStringList; + private RealmList fieldBinaryList; + private RealmList fieldBooleanList; + private RealmList fieldLongList; + private RealmList fieldIntegerList; + private RealmList fieldShortList; + private RealmList fieldByteList; + private RealmList fieldDoubleList; + private RealmList fieldFloatList; + private RealmList fieldDateList; + @LinkingObjects(FIELD_OBJECT) private final RealmResults objectParents = null; @@ -203,6 +226,86 @@ public void setFieldList(RealmList columnRealmList) { this.fieldList = columnRealmList; } + public RealmList getFieldStringList() { + return fieldStringList; + } + + public void setFieldStringList(RealmList fieldStringList) { + this.fieldStringList = fieldStringList; + } + + public RealmList getFieldBinaryList() { + return fieldBinaryList; + } + + public void setFieldBinaryList(RealmList fieldBinaryList) { + this.fieldBinaryList = fieldBinaryList; + } + + public RealmList getFieldBooleanList() { + return fieldBooleanList; + } + + public void setFieldBooleanList(RealmList fieldBooleanList) { + this.fieldBooleanList = fieldBooleanList; + } + + public RealmList getFieldLongList() { + return fieldLongList; + } + + public void setFieldLongList(RealmList fieldLongList) { + this.fieldLongList = fieldLongList; + } + + public RealmList getFieldIntegerList() { + return fieldIntegerList; + } + + public void setFieldIntegerList(RealmList fieldIntegerList) { + this.fieldIntegerList = fieldIntegerList; + } + + public RealmList getFieldShortList() { + return fieldShortList; + } + + public void setFieldShortList(RealmList fieldShortList) { + this.fieldShortList = fieldShortList; + } + + public RealmList getFieldByteList() { + return fieldByteList; + } + + public void setFieldByteList(RealmList fieldByteList) { + this.fieldByteList = fieldByteList; + } + + public RealmList getFieldDoubleList() { + return fieldDoubleList; + } + + public void setFieldDoubleList(RealmList fieldDoubleList) { + this.fieldDoubleList = fieldDoubleList; + } + + public RealmList getFieldFloatList() { + return fieldFloatList; + } + + public void setFieldFloatList(RealmList fieldFloatList) { + this.fieldFloatList = fieldFloatList; + } + + public RealmList getFieldDateList() { + return fieldDateList; + } + + public void setFieldDateList(RealmList fieldDateList) { + this.fieldDateList = fieldDateList; + } + public RealmResults getObjectParents() { return objectParents; } diff --git a/realm/realm-library/src/androidTest/java/io/realm/entities/NullTypes.java b/realm/realm-library/src/androidTest/java/io/realm/entities/NullTypes.java index db8d4a2dbb..47842e8796 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/entities/NullTypes.java +++ b/realm/realm-library/src/androidTest/java/io/realm/entities/NullTypes.java @@ -66,6 +66,27 @@ public class NullTypes extends RealmObject { public static final String FIELD_LO_OBJECT = "objectParents"; public static final String FIELD_LO_LIST = "listParents"; + public static final String FIELD_STRING_LIST_NOT_NULL = "fieldStringListNotNull"; + public static final String FIELD_STRING_LIST_NULL = "fieldStringListNull"; + public static final String FIELD_BINARY_LIST_NOT_NULL = "fieldBinaryListNotNull"; + public static final String FIELD_BINARY_LIST_NULL = "fieldBinaryListNull"; + public static final String FIELD_BOOLEAN_LIST_NOT_NULL = "fieldBooleanListNotNull"; + public static final String FIELD_BOOLEAN_LIST_NULL = "fieldBooleanListNull"; + public static final String FIELD_LONG_LIST_NOT_NULL = "fieldLongListNotNull"; + public static final String FIELD_LONG_LIST_NULL = "fieldLongListNull"; + public static final String FIELD_INTEGER_LIST_NOT_NULL = "fieldIntegerListNotNull"; + public static final String FIELD_INTEGER_LIST_NULL = "fieldIntegerListNull"; + public static final String FIELD_SHORT_LIST_NOT_NULL = "fieldShortListNotNull"; + public static final String FIELD_SHORT_LIST_NULL = "fieldShortListNull"; + public static final String FIELD_BYTE_LIST_NOT_NULL = "fieldByteListNotNull"; + public static final String FIELD_BYTE_LIST_NULL = "fieldByteListNull"; + public static final String FIELD_DOUBLE_LIST_NOT_NULL = "fieldDoubleListNotNull"; + public static final String FIELD_DOUBLE_LIST_NULL = "fieldDoubleListNull"; + public static final String FIELD_FLOAT_LIST_NOT_NULL = "fieldFloatListNotNull"; + public static final String FIELD_FLOAT_LIST_NULL = "fieldFloatListNull"; + public static final String FIELD_DATE_LIST_NOT_NULL = "fieldDateListNotNull"; + public static final String FIELD_DATE_LIST_NULL = "fieldDateListNull"; + @PrimaryKey private int id; @@ -114,6 +135,46 @@ public class NullTypes extends RealmObject { // never nullable private RealmList fieldListNull; + @Required + private RealmList fieldStringListNotNull; + private RealmList fieldStringListNull; + + @Required + private RealmList fieldBinaryListNotNull; + private RealmList fieldBinaryListNull; + + @Required + private RealmList fieldBooleanListNotNull; + private RealmList fieldBooleanListNull; + + @Required + private RealmList fieldLongListNotNull; + private RealmList fieldLongListNull; + + @Required + private RealmList fieldIntegerListNotNull; + private RealmList fieldIntegerListNull; + + @Required + private RealmList fieldShortListNotNull; + private RealmList fieldShortListNull; + + @Required + private RealmList fieldByteListNotNull; + private RealmList fieldByteListNull; + + @Required + private RealmList fieldDoubleListNotNull; + private RealmList fieldDoubleListNull; + + @Required + private RealmList fieldFloatListNotNull; + private RealmList fieldFloatListNull; + + @Required + private RealmList fieldDateListNotNull; + private RealmList fieldDateListNull; + // never nullable @LinkingObjects(FIELD_OBJECT_NULL) private final RealmResults objectParents = null; @@ -313,4 +374,164 @@ public RealmResults getObjectParents() { public RealmResults getListParents() { return listParents; } + + public RealmList getFieldStringListNotNull() { + return fieldStringListNotNull; + } + + public void setFieldStringListNotNull(RealmList fieldStringListNotNull) { + this.fieldStringListNotNull = fieldStringListNotNull; + } + + public RealmList getFieldStringListNull() { + return fieldStringListNull; + } + + public void setFieldStringListNull(RealmList fieldStringListNull) { + this.fieldStringListNull = fieldStringListNull; + } + + public RealmList getFieldBinaryListNotNull() { + return fieldBinaryListNotNull; + } + + public void setFieldBinaryListNotNull(RealmList fieldBinaryListNotNull) { + this.fieldBinaryListNotNull = fieldBinaryListNotNull; + } + + public RealmList getFieldBinaryListNull() { + return fieldBinaryListNull; + } + + public void setFieldBinaryListNull(RealmList fieldBinaryListNull) { + this.fieldBinaryListNull = fieldBinaryListNull; + } + + public RealmList getFieldBooleanListNotNull() { + return fieldBooleanListNotNull; + } + + public void setFieldBooleanListNotNull(RealmList fieldBooleanListNotNull) { + this.fieldBooleanListNotNull = fieldBooleanListNotNull; + } + + public RealmList getFieldBooleanListNull() { + return fieldBooleanListNull; + } + + public void setFieldBooleanListNull(RealmList fieldBooleanListNull) { + this.fieldBooleanListNull = fieldBooleanListNull; + } + + public RealmList getFieldLongListNotNull() { + return fieldLongListNotNull; + } + + public void setFieldLongListNotNull(RealmList fieldLongListNotNull) { + this.fieldLongListNotNull = fieldLongListNotNull; + } + + public RealmList getFieldLongListNull() { + return fieldLongListNull; + } + + public void setFieldLongListNull(RealmList fieldLongListNull) { + this.fieldLongListNull = fieldLongListNull; + } + + public RealmList getFieldIntegerListNotNull() { + return fieldIntegerListNotNull; + } + + public void setFieldIntegerListNotNull(RealmList fieldIntegerListNotNull) { + this.fieldIntegerListNotNull = fieldIntegerListNotNull; + } + + public RealmList getFieldIntegerListNull() { + return fieldIntegerListNull; + } + + public void setFieldIntegerListNull(RealmList fieldIntegerListNull) { + this.fieldIntegerListNull = fieldIntegerListNull; + } + + public RealmList getFieldShortListNotNull() { + return fieldShortListNotNull; + } + + public void setFieldShortListNotNull(RealmList fieldShortListNotNull) { + this.fieldShortListNotNull = fieldShortListNotNull; + } + + public RealmList getFieldShortListNull() { + return fieldShortListNull; + } + + public void setFieldShortListNull(RealmList fieldShortListNull) { + this.fieldShortListNull = fieldShortListNull; + } + + public RealmList getFieldByteListNotNull() { + return fieldByteListNotNull; + } + + public void setFieldByteListNotNull(RealmList fieldByteListNotNull) { + this.fieldByteListNotNull = fieldByteListNotNull; + } + + public RealmList getFieldByteListNull() { + return fieldByteListNull; + } + + public void setFieldByteListNull(RealmList fieldByteListNull) { + this.fieldByteListNull = fieldByteListNull; + } + + public RealmList getFieldDoubleListNotNull() { + return fieldDoubleListNotNull; + } + + public void setFieldDoubleListNotNull(RealmList fieldDoubleListNotNull) { + this.fieldDoubleListNotNull = fieldDoubleListNotNull; + } + + public RealmList getFieldDoubleListNull() { + return fieldDoubleListNull; + } + + public void setFieldDoubleListNull(RealmList fieldDoubleListNull) { + this.fieldDoubleListNull = fieldDoubleListNull; + } + + public RealmList getFieldFloatListNotNull() { + return fieldFloatListNotNull; + } + + public void setFieldFloatListNotNull(RealmList fieldFloatListNotNull) { + this.fieldFloatListNotNull = fieldFloatListNotNull; + } + + public RealmList getFieldFloatListNull() { + return fieldFloatListNull; + } + + public void setFieldFloatListNull(RealmList fieldFloatListNull) { + this.fieldFloatListNull = fieldFloatListNull; + } + + public RealmList getFieldDateListNotNull() { + return fieldDateListNotNull; + } + + public void setFieldDateListNotNull(RealmList fieldDateListNotNull) { + this.fieldDateListNotNull = fieldDateListNotNull; + } + + public RealmList getFieldDateListNull() { + return fieldDateListNull; + } + + public void setFieldDateListNull(RealmList fieldDateListNull) { + this.fieldDateListNull = fieldDateListNull; + } } From d86453f8ce254daa37656f803b0bd18384fe60bc Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 6 Sep 2017 17:37:53 +0900 Subject: [PATCH 02/72] empty commit for part9 From 81d4061ce85132f35e4a24db9f89cd9fc65365e2 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 6 Sep 2017 20:54:39 +0900 Subject: [PATCH 03/72] implement logic for primitive list in RealmList --- .../src/main/java/io/realm/RealmList.java | 1056 ++++++++++++++--- .../src/main/java/io/realm/RealmQuery.java | 12 +- .../io/realm/rx/RealmObservableFactory.java | 20 +- .../java/io/realm/rx/RxObservableFactory.java | 4 +- 4 files changed, 907 insertions(+), 185 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index f454a013eb..57e7db922a 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -59,6 +59,7 @@ public class RealmList extends AbstractList implements OrderedRealmCollect private static final String ONLY_IN_MANAGED_MODE_MESSAGE = "This method is only available in managed mode"; private static final String NULL_OBJECTS_NOT_ALLOWED_MESSAGE = "RealmList does not accept null values"; + private static final String INVALID_OBJECT_TYPE_MESSAGE = "Unacceptable value type. Acceptable: %1$s, actual: %2$s"; public static final String REMOVE_OUTSIDE_TRANSACTION_ERROR = "Objects can only be removed from inside a write transaction"; private final io.realm.internal.Collection collection; @@ -67,10 +68,8 @@ public class RealmList extends AbstractList implements OrderedRealmCollect @Nullable protected String className; - // TODO implement this - private boolean forValues; - - final OsList osList; + // Always null if RealmList is unmanaged, always non-null is managed. + private final ManagedListOperator osListOperator; final protected BaseRealm realm; private List unmanagedList; @@ -83,8 +82,8 @@ public class RealmList extends AbstractList implements OrderedRealmCollect */ public RealmList() { collection = null; - osList = null; realm = null; + osListOperator = null; unmanagedList = new ArrayList<>(); } @@ -97,14 +96,15 @@ public RealmList() { * * @param objects initial objects in the list. */ + @SafeVarargs public RealmList(E... objects) { //noinspection ConstantConditions if (objects == null) { throw new IllegalArgumentException("The objects argument cannot be null"); } collection = null; - osList = null; realm = null; + osListOperator = null; unmanagedList = new ArrayList<>(objects.length); Collections.addAll(unmanagedList, objects); } @@ -119,15 +119,19 @@ public RealmList(E... objects) { RealmList(Class clazz, OsList osList, BaseRealm realm) { this.collection = new io.realm.internal.Collection(realm.sharedRealm, osList, null); this.clazz = clazz; - this.osList = osList; + osListOperator = getOperator(realm, osList, clazz); this.realm = realm; } RealmList(String className, OsList osList, BaseRealm realm) { this.collection = new io.realm.internal.Collection(realm.sharedRealm, osList, null); - this.osList = osList; this.realm = realm; this.className = className; + osListOperator = getOperator(realm, osList, null); + } + + OsList getOsList() { + return osListOperator.getOsList(); } /** @@ -154,7 +158,7 @@ public boolean isManaged() { } private boolean isAttached() { - return osList != null && osList.isValid(); + return osListOperator != null && osListOperator.isValid(); } /** @@ -171,28 +175,18 @@ private boolean isAttached() { * * * @param location the index at which to insert. - * @param object the object to add. + * @param element the element to add. * @throws IllegalStateException if Realm instance has been closed or container object has been removed. * @throws IndexOutOfBoundsException if {@code location < 0 || location > size()}. */ @Override - public void add(int location, @Nullable E object) { - if (forValues) { - // TODO implement this - return; - } - + public void add(int location, @Nullable E element) { //noinspection ConstantConditions - checkValidObject(object); if (isManaged()) { checkValidRealm(); - if (location < 0 || location > size()) { - throw new IndexOutOfBoundsException("Invalid index " + location + ", size is " + size()); - } - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) object); - osList.insertRow(location, proxy.realmGet$proxyState().getRow$realm().getIndex()); + osListOperator.insert(location, element); } else { - unmanagedList.add(location, object); + unmanagedList.add(location, element); } modCount++; } @@ -214,17 +208,11 @@ public void add(int location, @Nullable E object) { */ @Override public boolean add(@Nullable E object) { - if (forValues) { - // TODO implement this - return false; - } - //noinspection ConstantConditions - checkValidObject(object); if (isManaged()) { checkValidRealm(); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) object); - osList.addRow(proxy.realmGet$proxyState().getRow$realm().getIndex()); + //noinspection ConstantConditions + osListOperator.add(object); } else { unmanagedList.add(object); } @@ -251,74 +239,16 @@ public boolean add(@Nullable E object) { */ @Override public E set(int location, @Nullable E object) { - if (forValues) { - // TODO implement this - return null; - } - - //noinspection ConstantConditions - checkValidObject(object); E oldObject; if (isManaged()) { checkValidRealm(); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) object); - oldObject = get(location); - osList.setRow(location, proxy.realmGet$proxyState().getRow$realm().getIndex()); - return oldObject; + oldObject = osListOperator.set(location, object); } else { oldObject = unmanagedList.set(location, object); } return oldObject; } - // Transparently copies an unmanaged object or managed object from another Realm to the Realm backing this RealmList. - private T copyToRealmIfNeeded(T object) { - if (object instanceof RealmObjectProxy) { - RealmObjectProxy proxy = (RealmObjectProxy) object; - - if (proxy instanceof DynamicRealmObject) { - //noinspection ConstantConditions - @Nonnull - String listClassName = className; - if (proxy.realmGet$proxyState().getRealm$realm() == realm) { - String objectClassName = ((DynamicRealmObject) object).getType(); - if (listClassName.equals(objectClassName)) { - // Same Realm instance and same target table - return object; - } else { - // Different target table - throw new IllegalArgumentException(String.format(Locale.US, - "The object has a different type from list's." + - " Type of the list is '%s', type of object is '%s'.", listClassName, objectClassName)); - } - } else if (realm.threadId == proxy.realmGet$proxyState().getRealm$realm().threadId) { - // We don't support moving DynamicRealmObjects across Realms automatically. The overhead is too big as - // you have to run a full schema validation for each object. - // And copying from another Realm instance pointed to the same Realm file is not supported as well. - throw new IllegalArgumentException("Cannot copy DynamicRealmObject between Realm instances."); - } else { - throw new IllegalStateException("Cannot copy an object to a Realm instance created in another thread."); - } - } else { - // Object is already in this realm - if (proxy.realmGet$proxyState().getRow$realm() != null && proxy.realmGet$proxyState().getRealm$realm().getPath().equals(realm.getPath())) { - if (realm != proxy.realmGet$proxyState().getRealm$realm()) { - throw new IllegalArgumentException("Cannot copy an object from another Realm instance."); - } - return object; - } - } - } - - // At this point the object can only be a typed object, so the backing Realm cannot be a DynamicRealm. - Realm realm = (Realm) this.realm; - if (realm.getTable(object.getClass()).hasPrimaryKey()) { - return realm.copyToRealmOrUpdate(object); - } else { - return realm.copyToRealm(object); - } - } - /** * Moves an object from one position to another, while maintaining a fixed sized list. * RealmObjects will be shifted so no {@code null} values are introduced. @@ -332,10 +262,15 @@ private T copyToRealmIfNeeded(T object) { public void move(int oldPos, int newPos) { if (isManaged()) { checkValidRealm(); - osList.move(oldPos, newPos); + osListOperator.move(oldPos, newPos); } else { - checkIndex(oldPos); - checkIndex(newPos); + final int listSize = unmanagedList.size(); + if (oldPos < 0 || listSize <= oldPos) { + throw new IndexOutOfBoundsException("Invalid index " + oldPos + ", size is " + listSize); + } + if (newPos < 0 || listSize <= newPos) { + throw new IndexOutOfBoundsException("Invalid index " + newPos + ", size is " + listSize); + } E object = unmanagedList.remove(oldPos); if (newPos > oldPos) { unmanagedList.add(newPos - 1, object); @@ -357,7 +292,7 @@ public void move(int oldPos, int newPos) { public void clear() { if (isManaged()) { checkValidRealm(); - osList.removeAll(); + osListOperator.removeAll(); } else { unmanagedList.clear(); } @@ -378,7 +313,7 @@ public E remove(int location) { if (isManaged()) { checkValidRealm(); removedItem = get(location); - osList.remove(location); + osListOperator.remove(location); } else { removedItem = unmanagedList.remove(location); } @@ -441,7 +376,7 @@ public boolean removeAll(Collection collection) { @Override public boolean deleteFirstFromRealm() { if (isManaged()) { - if (size() > 0) { + if (!osListOperator.isEmpty()) { deleteFromRealm(0); modCount++; return true; @@ -459,8 +394,8 @@ public boolean deleteFirstFromRealm() { @Override public boolean deleteLastFromRealm() { if (isManaged()) { - if (size() > 0) { - deleteFromRealm(size() - 1); + if (!osListOperator.isEmpty()) { + osListOperator.removeLast(); modCount++; return true; } else { @@ -482,15 +417,9 @@ public boolean deleteLastFromRealm() { @Override @Nullable public E get(int location) { - if (forValues) { - // TODO implement this - return null; - } - if (isManaged()) { checkValidRealm(); - //noinspection unchecked - return (E) realm.get((Class) clazz, className, osList.getUncheckedRow(location)); + return osListOperator.get(location); } else { return unmanagedList.get(location); } @@ -518,7 +447,7 @@ public E first(@Nullable E defaultValue) { private E firstImpl(boolean shouldThrow, @Nullable E defaultValue) { if (isManaged()) { checkValidRealm(); - if (!osList.isEmpty()) { + if (!osListOperator.isEmpty()) { return get(0); } } else if (unmanagedList != null && !unmanagedList.isEmpty()) { @@ -554,8 +483,8 @@ public E last(@Nullable E defaultValue) { private E lastImpl(boolean shouldThrow, @Nullable E defaultValue) { if (isManaged()) { checkValidRealm(); - if (!osList.isEmpty()) { - return get((int) osList.size() - 1); + if (!osListOperator.isEmpty()) { + return get(osListOperator.size() - 1); } } else if (unmanagedList != null && !unmanagedList.isEmpty()) { return unmanagedList.get(unmanagedList.size() - 1); @@ -615,7 +544,7 @@ public RealmResults sort(String[] fieldNames, Sort[] sortOrders) { public void deleteFromRealm(int location) { if (isManaged()) { checkValidRealm(); - osList.remove(location); + osListOperator.remove(location); modCount++; } else { throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); @@ -632,8 +561,7 @@ public void deleteFromRealm(int location) { public int size() { if (isManaged()) { checkValidRealm(); - long size = osList.size(); - return size < Integer.MAX_VALUE ? (int) size : Integer.MAX_VALUE; + return osListOperator.size(); } else { return unmanagedList.size(); } @@ -739,8 +667,8 @@ public Date minDate(String fieldName) { public boolean deleteAllFromRealm() { if (isManaged()) { checkValidRealm(); - if (size() > 0) { - osList.deleteAll(); + if (!osListOperator.isEmpty()) { + osListOperator.removeAll(); modCount++; return true; } else { @@ -836,20 +764,6 @@ public ListIterator listIterator(int location) { } } - private void checkValidObject(E object) { - //noinspection ConstantConditions - if (object == null) { - throw new IllegalArgumentException(NULL_OBJECTS_NOT_ALLOWED_MESSAGE); - } - } - - private void checkIndex(int location) { - int size = size(); - if (location < 0 || location >= size) { - throw new IndexOutOfBoundsException("Invalid index " + location + ", size is " + size); - } - } - private void checkValidRealm() { realm.checkIfValid(); } @@ -866,47 +780,74 @@ public OrderedRealmCollectionSnapshot createSnapshot() { if (className != null) { return new OrderedRealmCollectionSnapshot<>( realm, - new io.realm.internal.Collection(realm.sharedRealm, osList, null), + new io.realm.internal.Collection(realm.sharedRealm, osListOperator.getOsList(), null), className); } else { // 'clazz' is non-null when 'dynamicClassName' is null. //noinspection ConstantConditions return new OrderedRealmCollectionSnapshot<>( realm, - new io.realm.internal.Collection(realm.sharedRealm, osList, null), + new io.realm.internal.Collection(realm.sharedRealm, osListOperator.getOsList(), null), clazz); } } @Override public String toString() { - if (forValues) { - // TODO implement this - return ""; - } - - StringBuilder sb = new StringBuilder(); + final StringBuilder sb = new StringBuilder("RealmList<"); if (isManaged()) { - // 'clazz' is non-null when 'dynamicClassName' is null. - //noinspection ConstantConditions,unchecked - sb.append(className != null ? className : realm.getSchema().getSchemaForClass((Class) clazz).getClassName()); + if (className != null) { + sb.append(className); + } else { + // 'clazz' is non-null when 'dynamicClassName' is null. + //noinspection ConstantConditions,unchecked + if (isClassForRealmModel(clazz)) { + //noinspection ConstantConditions,unchecked + sb.append(realm.getSchema().getSchemaForClass((Class) clazz).getClassName()); + } else { + sb.append(clazz.getSimpleName()); + } + } } else { - sb.append(getClass().getSimpleName()); + // unmanaged RealmList does not know actual element type. + sb.append("?"); } - sb.append("@["); - if (isManaged() && !isAttached()) { - sb.append("invalid"); - } else { - for (int i = 0; i < size(); i++) { - if (isManaged()) { + sb.append(">@["); + final String separator = ","; + if (isManaged()) { + if (!isAttached()) { + sb.append("invalid"); + } else if (isClassForRealmModel(clazz)) { + for (int i = 0; i < size(); i++) { + //noinspection ConstantConditions sb.append(((RealmObjectProxy) get(i)).realmGet$proxyState().getRow$realm().getIndex()); - } else { - sb.append(System.identityHashCode(get(i))); + sb.append(separator); } - if (i < size() - 1) { - sb.append(','); + if (0 < size()) { + sb.setLength(sb.length() - separator.length()); + } + } else { + for (int i = 0; i < size(); i++) { + sb.append(get(i)); + sb.append(separator); + } + if (0 < size()) { + sb.setLength(sb.length() - separator.length()); } } + } else { + for (int i = 0; i < size(); i++) { + final E value = get(i); + if (value instanceof RealmModel) { + sb.append(System.identityHashCode(value)); + } else { + sb.append(value); + } + sb.append(separator); + } + if (0 < size()) { + sb.setLength(sb.length() - separator.length()); + } } sb.append("]"); return sb.toString(); @@ -937,19 +878,13 @@ public String toString() { * corresponding Realm instance doesn't support RxJava. * @see RxJava and Realm */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "WeakerAccess"}) public Observable> asObservable() { - if (forValues) { - // TODO implement this - - } if (realm instanceof Realm) { return realm.configuration.getRxFactory().from((Realm) realm, this); } else if (realm instanceof DynamicRealm) { - DynamicRealm dynamicRealm = (DynamicRealm) realm; - RealmList dynamicList = (RealmList) this; @SuppressWarnings("UnnecessaryLocalVariable") - Observable results = realm.configuration.getRxFactory().from(dynamicRealm, dynamicList); + Observable results = realm.configuration.getRxFactory().from((DynamicRealm) realm, this); return results; } else { throw new UnsupportedOperationException(realm.getClass() + " does not support RxJava."); @@ -1257,15 +1192,802 @@ public void add(@Nullable E e) { } } - /* - * MEMO: This method supports {@code long}, {@code int}, {@code short}, {@code byte}, - * {@code double}, {@code float} and {@code boolean} as {@code T} in addition to classes - * mentioned in the class comment of {@link RealmValueList}. - */ - @Nonnull - @Override - public T[] toArray(@Nonnull T[] a) { - // TODO implement this - return super.toArray(a); + @SuppressWarnings("WeakerAccess") + public long[] toLongArray(@SuppressWarnings("SameParameterValue") long valueForNull) { + if (clazz == null || Number.class.isAssignableFrom(clazz)) { + throw new IllegalStateException("toLongArray() is only supported when the element type is implementing 'java.lang.Number' interface."); + } + final int size = size(); + final long[] result = new long[size]; + for (int i = 0; i < size; i++) { + final E element = osListOperator.get(i); + result[i] = (element == null) ? valueForNull : ((Number) element).longValue(); + } + return result; + } + + public long[] toLongArray() { + return toLongArray(0L); + } + + @SuppressWarnings("WeakerAccess") + public int[] toIntArray(@SuppressWarnings("SameParameterValue") int valueForNull) { + if (clazz == null || Number.class.isAssignableFrom(clazz)) { + throw new IllegalStateException("toIntArray() is only supported when the element type is implementing 'java.lang.Number' interface."); + } + final int size = size(); + final int[] result = new int[size]; + for (int i = 0; i < size; i++) { + final E element = osListOperator.get(i); + result[i] = (element == null) ? valueForNull : ((Number) element).intValue(); + } + return result; + } + + public int[] toIntArray() { + return toIntArray(0); + } + + @SuppressWarnings("WeakerAccess") + public short[] toShortArray(@SuppressWarnings("SameParameterValue") short valueForNull) { + if (clazz == null || Number.class.isAssignableFrom(clazz)) { + throw new IllegalStateException("toShortArray() is only supported when the element type is implementing 'java.lang.Number' interface."); + } + final int size = size(); + final short[] result = new short[size]; + for (int i = 0; i < size; i++) { + final E element = osListOperator.get(i); + result[i] = (element == null) ? valueForNull : ((Number) element).shortValue(); + } + return result; + } + + public short[] toShortArray() { + return toShortArray((short) 0); + } + + @SuppressWarnings("WeakerAccess") + public byte[] toByteArray(@SuppressWarnings("SameParameterValue") byte valueForNull) { + if (clazz == null || Number.class.isAssignableFrom(clazz)) { + throw new IllegalStateException("toByteArray() is only supported when the element type is implementing 'java.lang.Number' interface."); + } + final int size = size(); + final byte[] result = new byte[size]; + for (int i = 0; i < size; i++) { + final E element = osListOperator.get(i); + result[i] = (element == null) ? valueForNull : ((Number) element).byteValue(); + } + return result; + } + public byte[] toByteArray() { + return toByteArray((byte) 0); + } + + @SuppressWarnings("WeakerAccess") + public boolean[] toBooleanArray(@SuppressWarnings("SameParameterValue") boolean valueForNull) { + if (clazz != Boolean.class) { + throw new IllegalStateException("toBooleanArray() is only supported when the element type is 'java.lang.Boolean'."); + } + final int size = size(); + final boolean[] result = new boolean[size]; + for (int i = 0; i < size; i++) { + final E element = osListOperator.get(i); + result[i] = (element == null) ? valueForNull : (Boolean) element; + } + return result; + } + + public boolean[] toBooleanArray() { + return toBooleanArray(false); + } + + @SuppressWarnings("WeakerAccess") + public double[] toDoubleArray(@SuppressWarnings("SameParameterValue") double valueForNull) { + if (clazz == null || Number.class.isAssignableFrom(clazz)) { + throw new IllegalStateException("toDoubleArray() is only supported when the element type is implementing 'java.lang.Number' interface."); + } + + final int size = size(); + final double[] result = new double[size]; + for (int i = 0; i < size; i++) { + final E element = osListOperator.get(i); + result[i] = (element == null) ? valueForNull : ((Number) element).doubleValue(); + } + return result; + } + + public double[] toDoubleArray() { + return toDoubleArray(0D); + } + + @SuppressWarnings("WeakerAccess") + public float[] toFloatArray(@SuppressWarnings("SameParameterValue") float valueForNull) { + if (clazz == null || Number.class.isAssignableFrom(clazz)) { + throw new IllegalStateException("toFloatArray() is only supported when the element type is implementing 'java.lang.Number' interface."); + } + + final int size = size(); + final float[] result = new float[size]; + for (int i = 0; i < size; i++) { + final E element = osListOperator.get(i); + result[i] = (element == null) ? valueForNull : ((Number) element).floatValue(); + } + return result; + } + + public float[] toFloatArray() { + return toFloatArray(0F); + } + + private static boolean isClassForRealmModel(Class clazz) { + return RealmModel.class.isAssignableFrom(clazz); + } + + private ManagedListOperator getOperator(BaseRealm realm, OsList osList, @Nullable Class clazz) { + if (clazz == null || isClassForRealmModel(clazz)) { + return new RealmModelListOperator<>(realm, osList, clazz, className); + } + if (clazz == String.class) { + //noinspection unchecked + return (ManagedListOperator) new StringListOperator(realm, osList, (Class) clazz); + } + if (clazz == Long.class || clazz == Integer.class || clazz == Short.class || clazz == Byte.class) { + return new LongListOperator<>(realm, osList, clazz); + } + if (clazz == Boolean.class) { + //noinspection unchecked + return (ManagedListOperator) new BooleanListOperator(realm, osList, (Class) clazz); + } + if (clazz == byte[].class) { + //noinspection unchecked + return (ManagedListOperator) new BinaryListOperator(realm, osList, (Class) clazz); + } + if (clazz == Double.class) { + //noinspection unchecked + return (ManagedListOperator) new DoubleListOperator(realm, osList, (Class) clazz); + } + if (clazz == Float.class) { + //noinspection unchecked + return (ManagedListOperator) new FloatListOperator(realm, osList, (Class) clazz); + } + if (clazz == Date.class) { + //noinspection unchecked + return (ManagedListOperator) new DateListOperator(realm, osList, (Class) clazz); + } + throw new IllegalArgumentException("Unexpected value class: " + clazz.getName()); + } + + private static abstract class ManagedListOperator { + final BaseRealm realm; + final OsList osList; + @Nullable + final Class clazz; + + ManagedListOperator(BaseRealm realm, OsList osList, @Nullable Class clazz) { + this.realm = realm; + this.clazz = clazz; + this.osList = osList; + } + + OsList getOsList() { + return osList; + } + + final boolean isValid() { + return osList.isValid(); + } + + final int size() { + final long actualSize = osList.size(); + return actualSize < Integer.MAX_VALUE ? (int) actualSize : Integer.MAX_VALUE; + } + + final boolean isEmpty() { + return osList.isEmpty(); + } + + final void checkInsertIndex(int index) { + final int size = size(); + if (index < 0 || size < index) { + throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); + } + } + + final void checkElementExists(int index) { + final int size = size(); + if (index < 0 || size <= index) { + throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); + } + } + + @Nullable + abstract T get(int index); + abstract void add(@Nullable Object value); + abstract void insert(int index, @Nullable Object value); + @Nullable + abstract T set(int index, @Nullable Object value); + + final void move(int oldPos, int newPos) { + osList.move(oldPos, newPos); + } + + final void remove(int index) { + osList.remove(index); + } + + final void removeLast() { + osList.remove(osList.size() - 1); + } + + final void removeAll() { + osList.removeAll(); + } + } + + private static final class RealmModelListOperator extends ManagedListOperator { + + @Nullable + private final String className; + + RealmModelListOperator(BaseRealm realm, OsList osList, @Nullable Class clazz, @Nullable String className) { + super(realm, osList, clazz); + this.className = className; + } + + @Override + T get(int index) { + //noinspection unchecked + return (T) realm.get((Class) clazz, className, osList.getUncheckedRow(index)); + } + + private void checkValidValue(@Nullable Object value) { + if (value == null) { + throw new IllegalArgumentException(NULL_OBJECTS_NOT_ALLOWED_MESSAGE); + } + if (!(value instanceof RealmModel)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.String", + value.getClass().getName())); + } + } + + @Override + public void add(@SuppressWarnings("NullableProblems") Object value) { + checkValidValue(value); + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); + osList.addRow(proxy.realmGet$proxyState().getRow$realm().getIndex()); + } + + @Override + public void insert(int index, @SuppressWarnings("NullableProblems") Object value) { + checkValidValue(value); + checkInsertIndex(index); + + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); + osList.insertRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); + } + + @Override + protected T set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); + + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); + //noinspection unchecked + final T oldObject = get(index); + osList.setRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); + return oldObject; + } + + // Transparently copies an unmanaged object or managed object from another Realm to the Realm backing this RealmList. + private E copyToRealmIfNeeded(E object) { + if (object instanceof RealmObjectProxy) { + RealmObjectProxy proxy = (RealmObjectProxy) object; + + if (proxy instanceof DynamicRealmObject) { + //noinspection ConstantConditions + @Nonnull + String listClassName = className; + if (proxy.realmGet$proxyState().getRealm$realm() == realm) { + String objectClassName = ((DynamicRealmObject) object).getType(); + if (listClassName.equals(objectClassName)) { + // Same Realm instance and same target table + return object; + } else { + // Different target table + throw new IllegalArgumentException(String.format(Locale.US, + "The object has a different type from list's." + + " Type of the list is '%s', type of object is '%s'.", listClassName, objectClassName)); + } + } else if (realm.threadId == proxy.realmGet$proxyState().getRealm$realm().threadId) { + // We don't support moving DynamicRealmObjects across Realms automatically. The overhead is too big as + // you have to run a full schema validation for each object. + // And copying from another Realm instance pointed to the same Realm file is not supported as well. + throw new IllegalArgumentException("Cannot copy DynamicRealmObject between Realm instances."); + } else { + throw new IllegalStateException("Cannot copy an object to a Realm instance created in another thread."); + } + } else { + // Object is already in this realm + if (proxy.realmGet$proxyState().getRow$realm() != null && proxy.realmGet$proxyState().getRealm$realm().getPath().equals(realm.getPath())) { + if (realm != proxy.realmGet$proxyState().getRealm$realm()) { + throw new IllegalArgumentException("Cannot copy an object from another Realm instance."); + } + return object; + } + } + } + + // At this point the object can only be a typed object, so the backing Realm cannot be a DynamicRealm. + Realm realm = (Realm) this.realm; + if (realm.getTable(object.getClass()).hasPrimaryKey()) { + return realm.copyToRealmOrUpdate(object); + } else { + return realm.copyToRealm(object); + } + } + } + + private static final class StringListOperator extends ManagedListOperator { + + StringListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } + + @Nullable + @Override + String get(int index) { + return (String) osList.getValue(index); + } + + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof String)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.String", + value.getClass().getName())); + } + } + + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addString((String) value); + } + } + + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); + + if (value == null) { + osList.insertNull(index); + } else { + osList.insertString(index, (String) value); + } + } + + @Override + @Nullable + protected String set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); + + final String oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setString(index, (String) value); + } + return oldValue; + } + } + + private static final class LongListOperator extends ManagedListOperator { + + LongListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } + + @Nullable + @Override + T get(int index) { + final Long value = (Long) osList.getValue(index); + if (value == null) { + return null; + } + if (clazz == Long.class) { + //noinspection unchecked + return (T) value; + } + if (clazz == Integer.class) { + //noinspection unchecked,UnnecessaryBoxing,ConstantConditions + return clazz.cast(Integer.valueOf(value.intValue())); + } + if (clazz == Short.class) { + //noinspection unchecked,UnnecessaryBoxing,ConstantConditions + return clazz.cast(Short.valueOf(value.shortValue())); + } + if (clazz == Byte.class) { + //noinspection unchecked,UnnecessaryBoxing,ConstantConditions + return clazz.cast(Byte.valueOf(value.byteValue())); + } + //noinspection ConstantConditions + throw new IllegalStateException("Unexpected element type: " + clazz.getName()); + } + + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Number)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.Long, java.lang.Integer, java.lang.Short, java.lang.Byte", + value.getClass().getName())); + } + } + + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addLong(((Number) value).longValue()); + } + } + + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); + + if (value == null) { + osList.insertNull(index); + } else { + osList.insertLong(index, ((Number) value).longValue()); + } + } + + @Nullable + @Override + protected T set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); + + final T oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setLong(index, ((Number) value).longValue()); + } + return oldValue; + } + } + + private static final class BooleanListOperator extends ManagedListOperator { + + BooleanListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } + + @Nullable + @Override + Boolean get(int index) { + return (Boolean) osList.getValue(index); + } + + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Boolean)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.Boolean", + value.getClass().getName())); + } + } + + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addBoolean((Boolean) value); + } + } + + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); + + if (value == null) { + osList.insertNull(index); + } else { + osList.insertBoolean(index, (Boolean) value); + } + } + + @Nullable + @Override + protected Boolean set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); + + final Boolean oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setBoolean(index, (Boolean) value); + } + return oldValue; + } + } + + private static final class BinaryListOperator extends ManagedListOperator { + + BinaryListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } + + @Nullable + @Override + byte[] get(int index) { + return (byte[]) osList.getValue(index); + } + + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof byte[])) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "byte[]", + value.getClass().getName())); + } + } + + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addBinary((byte[]) value); + } + } + + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); + + if (value == null) { + osList.insertNull(index); + } else { + osList.insertBinary(index, (byte[]) value); + } + } + + @Nullable + @Override + protected byte[] set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); + + final byte[] oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setBinary(index, (byte[]) value); + } + return oldValue; + } + } + + private static final class DoubleListOperator extends ManagedListOperator { + + DoubleListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } + + @Nullable + @Override + Double get(int index) { + return (Double) osList.getValue(index); + } + + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Number)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.Number", + value.getClass().getName())); + } + } + + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addDouble(((Number) value).doubleValue()); + } + } + + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); + + if (value == null) { + osList.insertNull(index); + } else { + osList.insertDouble(index, ((Number) value).doubleValue()); + } + } + + @Nullable + @Override + protected Double set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); + + final Double oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setDouble(index, ((Number) value).doubleValue()); + } + return oldValue; + } + } + + private static final class FloatListOperator extends ManagedListOperator { + + FloatListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } + + @Nullable + @Override + Float get(int index) { + return (Float) osList.getValue(index); + } + + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Number)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.Number", + value.getClass().getName())); + } + } + + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addFloat(((Number) value).floatValue()); + } + } + + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); + + if (value == null) { + osList.insertNull(index); + } else { + osList.insertFloat(index, ((Number) value).floatValue()); + } + } + + @Nullable + @Override + protected Float set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); + + final Float oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setFloat(index, ((Number) value).floatValue()); + } + return oldValue; + } + } + + private static final class DateListOperator extends ManagedListOperator { + + DateListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } + + @Nullable + @Override + Date get(int index) { + return (Date) osList.getValue(index); + } + + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Date)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.util.Date", + value.getClass().getName())); + } + } + + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addDate((Date) value); + } + } + + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); + + if (value == null) { + osList.insertNull(index); + } else { + osList.insertDate(index, (Date) value); + } + } + + @Nullable + @Override + protected Date set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); + + final Date oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setDate(index, (Date) value); + } + return oldValue; + } } } diff --git a/realm/realm-library/src/main/java/io/realm/RealmQuery.java b/realm/realm-library/src/main/java/io/realm/RealmQuery.java index 647ba03dbf..5081ecfbc4 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmQuery.java +++ b/realm/realm-library/src/main/java/io/realm/RealmQuery.java @@ -76,7 +76,7 @@ public class RealmQuery { * @return {@link RealmQuery} object. After building the query call one of the {@code find*} methods * to run it. */ - public static RealmQuery createQuery(Realm realm, Class clazz) { + static RealmQuery createQuery(Realm realm, Class clazz) { return new RealmQuery<>(realm, clazz); } @@ -88,7 +88,7 @@ public static RealmQuery createQuery(Realm realm, Clas * @return {@link RealmQuery} object. After building the query call one of the {@code find*} methods * to run it. */ - public static RealmQuery createDynamicQuery(DynamicRealm realm, String className) { + static RealmQuery createDynamicQuery(DynamicRealm realm, String className) { return new RealmQuery<>(realm, className); } @@ -100,7 +100,7 @@ public static RealmQuery createDynamicQuery(DynamicRea * to run it. */ @SuppressWarnings("unchecked") - public static RealmQuery createQueryFromResult(RealmResults queryResults) { + static RealmQuery createQueryFromResult(RealmResults queryResults) { //noinspection ConstantConditions return (queryResults.classSpec == null) ? new RealmQuery(queryResults, queryResults.className) @@ -115,11 +115,11 @@ public static RealmQuery createQueryFromResult(RealmResults queryResul * to run it. */ @SuppressWarnings("unchecked") - public static RealmQuery createQueryFromList(RealmList list) { + static RealmQuery createQueryFromList(RealmList list) { //noinspection ConstantConditions return (list.clazz == null) - ? new RealmQuery(list.realm, list.osList, list.className) - : new RealmQuery(list.realm, list.osList, list.clazz); + ? new RealmQuery(list.realm, list.getOsList(), list.className) + : new RealmQuery(list.realm, list.getOsList(), list.clazz); } private static boolean isClassForRealmModel(Class clazz) { diff --git a/realm/realm-library/src/main/java/io/realm/rx/RealmObservableFactory.java b/realm/realm-library/src/main/java/io/realm/rx/RealmObservableFactory.java index ace8f54d69..df04077dde 100644 --- a/realm/realm-library/src/main/java/io/realm/rx/RealmObservableFactory.java +++ b/realm/realm-library/src/main/java/io/realm/rx/RealmObservableFactory.java @@ -168,19 +168,19 @@ public void call() { } @Override - public Observable> from(DynamicRealm realm, final RealmResults results) { + public Observable> from(DynamicRealm realm, final RealmResults results) { final RealmConfiguration realmConfig = realm.getConfiguration(); - return Observable.create(new Observable.OnSubscribe>() { + return Observable.create(new Observable.OnSubscribe>() { @Override - public void call(final Subscriber> subscriber) { + public void call(final Subscriber> subscriber) { // Gets instance to make sure that the Realm is open for as long as the // Observable is subscribed to it. final DynamicRealm observableRealm = DynamicRealm.getInstance(realmConfig); resultsRefs.get().acquireReference(results); - final RealmChangeListener> listener = new RealmChangeListener>() { + final RealmChangeListener> listener = new RealmChangeListener>() { @Override - public void onChange(RealmResults result) { + public void onChange(RealmResults result) { if (!subscriber.isUnsubscribed()) { subscriber.onNext(results); } @@ -240,19 +240,19 @@ public void call() { } @Override - public Observable> from(DynamicRealm realm, final RealmList list) { + public Observable> from(DynamicRealm realm, final RealmList list) { final RealmConfiguration realmConfig = realm.getConfiguration(); - return Observable.create(new Observable.OnSubscribe>() { + return Observable.create(new Observable.OnSubscribe>() { @Override - public void call(final Subscriber> subscriber) { + public void call(final Subscriber> subscriber) { // Gets instance to make sure that the Realm is open for as long as the // Observable is subscribed to it. final DynamicRealm observableRealm = DynamicRealm.getInstance(realmConfig); listRefs.get().acquireReference(list); - final RealmChangeListener> listener = new RealmChangeListener>() { + final RealmChangeListener> listener = new RealmChangeListener>() { @Override - public void onChange(RealmList result) { + public void onChange(RealmList result) { if (!subscriber.isUnsubscribed()) { subscriber.onNext(list); } diff --git a/realm/realm-library/src/main/java/io/realm/rx/RxObservableFactory.java b/realm/realm-library/src/main/java/io/realm/rx/RxObservableFactory.java index d6c6c19c1e..d5af8ff419 100644 --- a/realm/realm-library/src/main/java/io/realm/rx/RxObservableFactory.java +++ b/realm/realm-library/src/main/java/io/realm/rx/RxObservableFactory.java @@ -77,7 +77,7 @@ public interface RxObservableFactory { * @param realm {@link DynamicRealm} instance results are coming from. * @return Rx observable that emit all updates to the RealmResults. */ - Observable> from(DynamicRealm realm, RealmResults results); + Observable> from(DynamicRealm realm, RealmResults results); /** * Creates an Observable for a {@link RealmList}. It should emit the initial list when subscribed to and on each @@ -104,7 +104,7 @@ public interface RxObservableFactory { * @param list RealmList to listen to changes for. * @param realm {@link DynamicRealm} instance list is coming from. */ - Observable> from(DynamicRealm realm, RealmList list); + Observable> from(DynamicRealm realm, RealmList list); /** * Creates an Observable for a {@link RealmObject}. It should emit the initial object when subscribed to and on each From 14489f7577e0ea047142db789747e8e05a0ad510 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 6 Sep 2017 21:17:39 +0900 Subject: [PATCH 04/72] fix tests --- .../androidTest/java/io/realm/RealmConfigurationTests.java | 4 ++-- .../src/androidTest/java/io/realm/RealmListTests.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmConfigurationTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmConfigurationTests.java index e41d01b8fa..5bb6aabc8c 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmConfigurationTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmConfigurationTests.java @@ -716,7 +716,7 @@ public Observable> from(Realm realm, RealmResults results } @Override - public Observable> from(DynamicRealm realm, RealmResults results) { + public Observable> from(DynamicRealm realm, RealmResults results) { return null; } @@ -726,7 +726,7 @@ public Observable> from(Realm realm, RealmList list) { } @Override - public Observable> from(DynamicRealm realm, RealmList list) { + public Observable> from(DynamicRealm realm, RealmList list) { return null; } diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java index 057bc0d958..540b9848ee 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java @@ -1119,7 +1119,7 @@ public void createSnapshot_shouldUseTargetTable() { realm.commitTransaction(); assertEquals(sizeBefore - 1, collection.size()); - assertNotNull(collection.osList); - assertEquals(collection.osList.getTargetTable().getName(), snapshot.getTable().getName()); + assertNotNull(collection.getOsList()); + assertEquals(collection.getOsList().getTargetTable().getName(), snapshot.getTable().getName()); } } From c48d399ac518e4afe15ba8bda2d6a7a4826717df Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 6 Sep 2017 21:57:51 +0900 Subject: [PATCH 05/72] fix annotation processor unit tests --- .../io/realm/processor/ClassMetaData.java | 4 +- .../io/realm/AllTypesRealmProxy.java | 547 ++++++++- .../io/realm/NullTypesRealmProxy.java | 1088 ++++++++++++++++- .../test/resources/some/test/AllTypes.java | 12 + .../test/resources/some/test/NullTypes.java | 39 + 5 files changed, 1681 insertions(+), 9 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java index 34456085a5..94a56f7369 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java @@ -463,8 +463,8 @@ private boolean categorizeField(Element element) { if (Utils.isRealmList(field)) { // We only check @Required annotation. @org.jetbrains.annotations.NotNull annotation should not affect nullability of the list values. if (!hasRequiredAnnotation(field)) { - final TypeMirror elementTypeMirror = ((DeclaredType) field.asType()).getTypeArguments().get(0); - if (!Utils.isRealmModel(elementTypeMirror)) { + final List fieldTypeArguments = ((DeclaredType) field.asType()).getTypeArguments(); + if (fieldTypeArguments.isEmpty() || !Utils.isRealmModel(fieldTypeArguments.get(0))) { nullableValueListFields.add(field); } } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index 3a0310ee40..22aaa3a5f2 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -47,9 +47,19 @@ static final class AllTypesColumnInfo extends ColumnInfo { long columnMutableRealmIntegerIndex; long columnObjectIndex; long columnRealmListIndex; + long columnStringListIndex; + long columnBinaryListIndex; + long columnBooleanListIndex; + long columnLongListIndex; + long columnIntegerListIndex; + long columnShortListIndex; + long columnByteListIndex; + long columnDoubleListIndex; + long columnFloatListIndex; + long columnDateListIndex; AllTypesColumnInfo(OsSchemaInfo schemaInfo) { - super(10); + super(20); OsObjectSchemaInfo objectSchemaInfo = schemaInfo.getObjectSchemaInfo("AllTypes"); this.columnStringIndex = addColumnDetails("columnString", objectSchemaInfo); this.columnLongIndex = addColumnDetails("columnLong", objectSchemaInfo); @@ -61,6 +71,16 @@ static final class AllTypesColumnInfo extends ColumnInfo { this.columnMutableRealmIntegerIndex = addColumnDetails("columnMutableRealmInteger", objectSchemaInfo); this.columnObjectIndex = addColumnDetails("columnObject", objectSchemaInfo); this.columnRealmListIndex = addColumnDetails("columnRealmList", objectSchemaInfo); + this.columnStringListIndex = addColumnDetails("columnStringList", objectSchemaInfo); + this.columnBinaryListIndex = addColumnDetails("columnBinaryList", objectSchemaInfo); + this.columnBooleanListIndex = addColumnDetails("columnBooleanList", objectSchemaInfo); + this.columnLongListIndex = addColumnDetails("columnLongList", objectSchemaInfo); + this.columnIntegerListIndex = addColumnDetails("columnIntegerList", objectSchemaInfo); + this.columnShortListIndex = addColumnDetails("columnShortList", objectSchemaInfo); + this.columnByteListIndex = addColumnDetails("columnByteList", objectSchemaInfo); + this.columnDoubleListIndex = addColumnDetails("columnDoubleList", objectSchemaInfo); + this.columnFloatListIndex = addColumnDetails("columnFloatList", objectSchemaInfo); + this.columnDateListIndex = addColumnDetails("columnDateList", objectSchemaInfo); addBacklinkDetails(schemaInfo, "parentObjects", "AllTypes", "columnObject"); } @@ -88,6 +108,16 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { dst.columnMutableRealmIntegerIndex = src.columnMutableRealmIntegerIndex; dst.columnObjectIndex = src.columnObjectIndex; dst.columnRealmListIndex = src.columnRealmListIndex; + dst.columnStringListIndex = src.columnStringListIndex; + dst.columnBinaryListIndex = src.columnBinaryListIndex; + dst.columnBooleanListIndex = src.columnBooleanListIndex; + dst.columnLongListIndex = src.columnLongListIndex; + dst.columnIntegerListIndex = src.columnIntegerListIndex; + dst.columnShortListIndex = src.columnShortListIndex; + dst.columnByteListIndex = src.columnByteListIndex; + dst.columnDoubleListIndex = src.columnDoubleListIndex; + dst.columnFloatListIndex = src.columnFloatListIndex; + dst.columnDateListIndex = src.columnDateListIndex; } } @@ -105,6 +135,16 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { fieldNames.add("columnMutableRealmInteger"); fieldNames.add("columnObject"); fieldNames.add("columnRealmList"); + fieldNames.add("columnStringList"); + fieldNames.add("columnBinaryList"); + fieldNames.add("columnBooleanList"); + fieldNames.add("columnLongList"); + fieldNames.add("columnIntegerList"); + fieldNames.add("columnShortList"); + fieldNames.add("columnByteList"); + fieldNames.add("columnDoubleList"); + fieldNames.add("columnFloatList"); + fieldNames.add("columnDateList"); FIELD_NAMES = Collections.unmodifiableList(fieldNames); } @@ -115,6 +155,16 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { @Override protected long getColumnIndex() { return columnInfo.columnMutableRealmIntegerIndex; } }; private RealmList columnRealmListRealmList; + private RealmList columnStringListRealmList; + private RealmList columnBinaryListRealmList; + private RealmList columnBooleanListRealmList; + private RealmList columnLongListRealmList; + private RealmList columnIntegerListRealmList; + private RealmList columnShortListRealmList; + private RealmList columnByteListRealmList; + private RealmList columnDoubleListRealmList; + private RealmList columnFloatListRealmList; + private RealmList columnDateListRealmList; private RealmResults parentObjectsBacklinks; AllTypesRealmProxy() { @@ -376,6 +426,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (proxyState.getExcludeFields$realm().contains("columnRealmList")) { return; } + // if the list contains unmanaged RealmObjects, convert them to managed. if (value != null && !value.isManaged()) { final Realm realm = (Realm) proxyState.getRealm$realm(); final RealmList original = value; @@ -396,7 +447,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (value == null) { return; } - for (RealmModel linkedObject : (RealmList) value) { + for (RealmModel linkedObject : value) { if (!(RealmObject.isManaged(linkedObject) && RealmObject.isValid(linkedObject))) { throw new IllegalArgumentException("Each element of 'value' must be a valid managed object."); } @@ -407,6 +458,396 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } } + @Override + public RealmList realmGet$columnStringList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnStringListRealmList != null) { + return columnStringListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnStringListIndex); + columnStringListRealmList = new RealmList(java.lang.String.class, osList, proxyState.getRealm$realm()); + return columnStringListRealmList; + } + } + + @Override + public void realmSet$columnStringList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnStringList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnStringListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.String item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addString(item); + } + } + } + + @Override + public RealmList realmGet$columnBinaryList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnBinaryListRealmList != null) { + return columnBinaryListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnBinaryListIndex); + columnBinaryListRealmList = new RealmList(byte[].class, osList, proxyState.getRealm$realm()); + return columnBinaryListRealmList; + } + } + + @Override + public void realmSet$columnBinaryList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnBinaryList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnBinaryListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (byte[] item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addBinary(item); + } + } + } + + @Override + public RealmList realmGet$columnBooleanList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnBooleanListRealmList != null) { + return columnBooleanListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnBooleanListIndex); + columnBooleanListRealmList = new RealmList(java.lang.Boolean.class, osList, proxyState.getRealm$realm()); + return columnBooleanListRealmList; + } + } + + @Override + public void realmSet$columnBooleanList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnBooleanList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnBooleanListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Boolean item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addBoolean(item); + } + } + } + + @Override + public RealmList realmGet$columnLongList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnLongListRealmList != null) { + return columnLongListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnLongListIndex); + columnLongListRealmList = new RealmList(java.lang.Long.class, osList, proxyState.getRealm$realm()); + return columnLongListRealmList; + } + } + + @Override + public void realmSet$columnLongList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnLongList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnLongListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Long item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$columnIntegerList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnIntegerListRealmList != null) { + return columnIntegerListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnIntegerListIndex); + columnIntegerListRealmList = new RealmList(java.lang.Integer.class, osList, proxyState.getRealm$realm()); + return columnIntegerListRealmList; + } + } + + @Override + public void realmSet$columnIntegerList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnIntegerList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnIntegerListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Integer item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$columnShortList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnShortListRealmList != null) { + return columnShortListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnShortListIndex); + columnShortListRealmList = new RealmList(java.lang.Short.class, osList, proxyState.getRealm$realm()); + return columnShortListRealmList; + } + } + + @Override + public void realmSet$columnShortList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnShortList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnShortListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Short item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$columnByteList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnByteListRealmList != null) { + return columnByteListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnByteListIndex); + columnByteListRealmList = new RealmList(java.lang.Byte.class, osList, proxyState.getRealm$realm()); + return columnByteListRealmList; + } + } + + @Override + public void realmSet$columnByteList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnByteList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnByteListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Byte item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$columnDoubleList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnDoubleListRealmList != null) { + return columnDoubleListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnDoubleListIndex); + columnDoubleListRealmList = new RealmList(java.lang.Double.class, osList, proxyState.getRealm$realm()); + return columnDoubleListRealmList; + } + } + + @Override + public void realmSet$columnDoubleList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnDoubleList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnDoubleListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Double item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addDouble(item.doubleValue()); + } + } + } + + @Override + public RealmList realmGet$columnFloatList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnFloatListRealmList != null) { + return columnFloatListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnFloatListIndex); + columnFloatListRealmList = new RealmList(java.lang.Float.class, osList, proxyState.getRealm$realm()); + return columnFloatListRealmList; + } + } + + @Override + public void realmSet$columnFloatList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnFloatList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnFloatListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Float item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addFloat(item.floatValue()); + } + } + } + + @Override + public RealmList realmGet$columnDateList() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (columnDateListRealmList != null) { + return columnDateListRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnDateListIndex); + columnDateListRealmList = new RealmList(java.util.Date.class, osList, proxyState.getRealm$realm()); + return columnDateListRealmList; + } + } + + @Override + public void realmSet$columnDateList(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("columnDateList")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.columnDateListIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.util.Date item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addDate(item); + } + } + } + @Override public RealmResults realmGet$parentObjects() { BaseRealm realm = proxyState.getRealm$realm(); @@ -430,6 +871,16 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { builder.addPersistedProperty("columnMutableRealmInteger", RealmFieldType.INTEGER, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); builder.addPersistedLinkProperty("columnObject", RealmFieldType.OBJECT, "AllTypes"); builder.addPersistedLinkProperty("columnRealmList", RealmFieldType.LIST, "AllTypes"); + builder.addPersistedLinkProperty("columnStringList", RealmFieldType.LIST, "String"); + builder.addPersistedLinkProperty("columnBinaryList", RealmFieldType.LIST, "byte[]"); + builder.addPersistedLinkProperty("columnBooleanList", RealmFieldType.LIST, "Boolean"); + builder.addPersistedLinkProperty("columnLongList", RealmFieldType.LIST, "Long"); + builder.addPersistedLinkProperty("columnIntegerList", RealmFieldType.LIST, "Integer"); + builder.addPersistedLinkProperty("columnShortList", RealmFieldType.LIST, "Short"); + builder.addPersistedLinkProperty("columnByteList", RealmFieldType.LIST, "Byte"); + builder.addPersistedLinkProperty("columnDoubleList", RealmFieldType.LIST, "Double"); + builder.addPersistedLinkProperty("columnFloatList", RealmFieldType.LIST, "Float"); + builder.addPersistedLinkProperty("columnDateList", RealmFieldType.LIST, "Date"); builder.addComputedLinkProperty("parentObjects", "AllTypes", "columnObject"); return builder.build(); } @@ -453,7 +904,7 @@ public static List getFieldNames() { @SuppressWarnings("cast") public static some.test.AllTypes createOrUpdateUsingJsonObject(Realm realm, JSONObject json, boolean update) throws JSONException { - final List excludeFields = new ArrayList(2); + final List excludeFields = new ArrayList(12); some.test.AllTypes obj = null; if (update) { Table table = realm.getTable(some.test.AllTypes.class); @@ -481,6 +932,36 @@ public static some.test.AllTypes createOrUpdateUsingJsonObject(Realm realm, JSON if (json.has("columnRealmList")) { excludeFields.add("columnRealmList"); } + if (json.has("columnStringList")) { + excludeFields.add("columnStringList"); + } + if (json.has("columnBinaryList")) { + excludeFields.add("columnBinaryList"); + } + if (json.has("columnBooleanList")) { + excludeFields.add("columnBooleanList"); + } + if (json.has("columnLongList")) { + excludeFields.add("columnLongList"); + } + if (json.has("columnIntegerList")) { + excludeFields.add("columnIntegerList"); + } + if (json.has("columnShortList")) { + excludeFields.add("columnShortList"); + } + if (json.has("columnByteList")) { + excludeFields.add("columnByteList"); + } + if (json.has("columnDoubleList")) { + excludeFields.add("columnDoubleList"); + } + if (json.has("columnFloatList")) { + excludeFields.add("columnFloatList"); + } + if (json.has("columnDateList")) { + excludeFields.add("columnDateList"); + } if (json.has("columnString")) { if (json.isNull("columnString")) { obj = (io.realm.AllTypesRealmProxy) realm.createObjectInternal(some.test.AllTypes.class, null, true, excludeFields); @@ -661,6 +1142,16 @@ public static some.test.AllTypes createUsingJsonStream(Realm realm, JsonReader r } reader.endArray(); } + } else if (name.equals("columnStringList")) { + } else if (name.equals("columnBinaryList")) { + } else if (name.equals("columnBooleanList")) { + } else if (name.equals("columnLongList")) { + } else if (name.equals("columnIntegerList")) { + } else if (name.equals("columnShortList")) { + } else if (name.equals("columnByteList")) { + } else if (name.equals("columnDoubleList")) { + } else if (name.equals("columnFloatList")) { + } else if (name.equals("columnDateList")) { } else { reader.skipValue(); } @@ -765,6 +1256,16 @@ public static some.test.AllTypes copy(Realm realm, some.test.AllTypes newObject, } } + realmObjectCopy.realmSet$columnStringList(realmObjectSource.realmGet$columnStringList()); + realmObjectCopy.realmSet$columnBinaryList(realmObjectSource.realmGet$columnBinaryList()); + realmObjectCopy.realmSet$columnBooleanList(realmObjectSource.realmGet$columnBooleanList()); + realmObjectCopy.realmSet$columnLongList(realmObjectSource.realmGet$columnLongList()); + realmObjectCopy.realmSet$columnIntegerList(realmObjectSource.realmGet$columnIntegerList()); + realmObjectCopy.realmSet$columnShortList(realmObjectSource.realmGet$columnShortList()); + realmObjectCopy.realmSet$columnByteList(realmObjectSource.realmGet$columnByteList()); + realmObjectCopy.realmSet$columnDoubleList(realmObjectSource.realmGet$columnDoubleList()); + realmObjectCopy.realmSet$columnFloatList(realmObjectSource.realmGet$columnFloatList()); + realmObjectCopy.realmSet$columnDateList(realmObjectSource.realmGet$columnDateList()); return realmObject; } @@ -1174,6 +1675,46 @@ public String toString() { stringBuilder.append("{columnRealmList:"); stringBuilder.append("RealmList[").append(realmGet$columnRealmList().size()).append("]"); stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnStringList:"); + stringBuilder.append("RealmList[").append(realmGet$columnStringList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnBinaryList:"); + stringBuilder.append("RealmList[").append(realmGet$columnBinaryList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnBooleanList:"); + stringBuilder.append("RealmList[").append(realmGet$columnBooleanList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnLongList:"); + stringBuilder.append("RealmList[").append(realmGet$columnLongList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnIntegerList:"); + stringBuilder.append("RealmList[").append(realmGet$columnIntegerList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnShortList:"); + stringBuilder.append("RealmList[").append(realmGet$columnShortList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnByteList:"); + stringBuilder.append("RealmList[").append(realmGet$columnByteList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnDoubleList:"); + stringBuilder.append("RealmList[").append(realmGet$columnDoubleList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnFloatList:"); + stringBuilder.append("RealmList[").append(realmGet$columnFloatList().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{columnDateList:"); + stringBuilder.append("RealmList[").append(realmGet$columnDateList().size()).append("]"); + stringBuilder.append("}"); stringBuilder.append("]"); return stringBuilder.toString(); } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index ccacda2a95..d497fee814 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -57,9 +57,29 @@ static final class NullTypesColumnInfo extends ColumnInfo { long fieldDateNotNullIndex; long fieldDateNullIndex; long fieldObjectNullIndex; + long fieldStringListNotNullIndex; + long fieldStringListNullIndex; + long fieldBinaryListNotNullIndex; + long fieldBinaryListNullIndex; + long fieldBooleanListNotNullIndex; + long fieldBooleanListNullIndex; + long fieldLongListNotNullIndex; + long fieldLongListNullIndex; + long fieldIntegerListNotNullIndex; + long fieldIntegerListNullIndex; + long fieldShortListNotNullIndex; + long fieldShortListNullIndex; + long fieldByteListNotNullIndex; + long fieldByteListNullIndex; + long fieldDoubleListNotNullIndex; + long fieldDoubleListNullIndex; + long fieldFloatListNotNullIndex; + long fieldFloatListNullIndex; + long fieldDateListNotNullIndex; + long fieldDateListNullIndex; NullTypesColumnInfo(OsSchemaInfo schemaInfo) { - super(21); + super(41); OsObjectSchemaInfo objectSchemaInfo = schemaInfo.getObjectSchemaInfo("NullTypes"); this.fieldStringNotNullIndex = addColumnDetails("fieldStringNotNull", objectSchemaInfo); this.fieldStringNullIndex = addColumnDetails("fieldStringNull", objectSchemaInfo); @@ -82,6 +102,26 @@ static final class NullTypesColumnInfo extends ColumnInfo { this.fieldDateNotNullIndex = addColumnDetails("fieldDateNotNull", objectSchemaInfo); this.fieldDateNullIndex = addColumnDetails("fieldDateNull", objectSchemaInfo); this.fieldObjectNullIndex = addColumnDetails("fieldObjectNull", objectSchemaInfo); + this.fieldStringListNotNullIndex = addColumnDetails("fieldStringListNotNull", objectSchemaInfo); + this.fieldStringListNullIndex = addColumnDetails("fieldStringListNull", objectSchemaInfo); + this.fieldBinaryListNotNullIndex = addColumnDetails("fieldBinaryListNotNull", objectSchemaInfo); + this.fieldBinaryListNullIndex = addColumnDetails("fieldBinaryListNull", objectSchemaInfo); + this.fieldBooleanListNotNullIndex = addColumnDetails("fieldBooleanListNotNull", objectSchemaInfo); + this.fieldBooleanListNullIndex = addColumnDetails("fieldBooleanListNull", objectSchemaInfo); + this.fieldLongListNotNullIndex = addColumnDetails("fieldLongListNotNull", objectSchemaInfo); + this.fieldLongListNullIndex = addColumnDetails("fieldLongListNull", objectSchemaInfo); + this.fieldIntegerListNotNullIndex = addColumnDetails("fieldIntegerListNotNull", objectSchemaInfo); + this.fieldIntegerListNullIndex = addColumnDetails("fieldIntegerListNull", objectSchemaInfo); + this.fieldShortListNotNullIndex = addColumnDetails("fieldShortListNotNull", objectSchemaInfo); + this.fieldShortListNullIndex = addColumnDetails("fieldShortListNull", objectSchemaInfo); + this.fieldByteListNotNullIndex = addColumnDetails("fieldByteListNotNull", objectSchemaInfo); + this.fieldByteListNullIndex = addColumnDetails("fieldByteListNull", objectSchemaInfo); + this.fieldDoubleListNotNullIndex = addColumnDetails("fieldDoubleListNotNull", objectSchemaInfo); + this.fieldDoubleListNullIndex = addColumnDetails("fieldDoubleListNull", objectSchemaInfo); + this.fieldFloatListNotNullIndex = addColumnDetails("fieldFloatListNotNull", objectSchemaInfo); + this.fieldFloatListNullIndex = addColumnDetails("fieldFloatListNull", objectSchemaInfo); + this.fieldDateListNotNullIndex = addColumnDetails("fieldDateListNotNull", objectSchemaInfo); + this.fieldDateListNullIndex = addColumnDetails("fieldDateListNull", objectSchemaInfo); } NullTypesColumnInfo(ColumnInfo src, boolean mutable) { @@ -119,6 +159,26 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { dst.fieldDateNotNullIndex = src.fieldDateNotNullIndex; dst.fieldDateNullIndex = src.fieldDateNullIndex; dst.fieldObjectNullIndex = src.fieldObjectNullIndex; + dst.fieldStringListNotNullIndex = src.fieldStringListNotNullIndex; + dst.fieldStringListNullIndex = src.fieldStringListNullIndex; + dst.fieldBinaryListNotNullIndex = src.fieldBinaryListNotNullIndex; + dst.fieldBinaryListNullIndex = src.fieldBinaryListNullIndex; + dst.fieldBooleanListNotNullIndex = src.fieldBooleanListNotNullIndex; + dst.fieldBooleanListNullIndex = src.fieldBooleanListNullIndex; + dst.fieldLongListNotNullIndex = src.fieldLongListNotNullIndex; + dst.fieldLongListNullIndex = src.fieldLongListNullIndex; + dst.fieldIntegerListNotNullIndex = src.fieldIntegerListNotNullIndex; + dst.fieldIntegerListNullIndex = src.fieldIntegerListNullIndex; + dst.fieldShortListNotNullIndex = src.fieldShortListNotNullIndex; + dst.fieldShortListNullIndex = src.fieldShortListNullIndex; + dst.fieldByteListNotNullIndex = src.fieldByteListNotNullIndex; + dst.fieldByteListNullIndex = src.fieldByteListNullIndex; + dst.fieldDoubleListNotNullIndex = src.fieldDoubleListNotNullIndex; + dst.fieldDoubleListNullIndex = src.fieldDoubleListNullIndex; + dst.fieldFloatListNotNullIndex = src.fieldFloatListNotNullIndex; + dst.fieldFloatListNullIndex = src.fieldFloatListNullIndex; + dst.fieldDateListNotNullIndex = src.fieldDateListNotNullIndex; + dst.fieldDateListNullIndex = src.fieldDateListNullIndex; } } @@ -147,11 +207,51 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { fieldNames.add("fieldDateNotNull"); fieldNames.add("fieldDateNull"); fieldNames.add("fieldObjectNull"); + fieldNames.add("fieldStringListNotNull"); + fieldNames.add("fieldStringListNull"); + fieldNames.add("fieldBinaryListNotNull"); + fieldNames.add("fieldBinaryListNull"); + fieldNames.add("fieldBooleanListNotNull"); + fieldNames.add("fieldBooleanListNull"); + fieldNames.add("fieldLongListNotNull"); + fieldNames.add("fieldLongListNull"); + fieldNames.add("fieldIntegerListNotNull"); + fieldNames.add("fieldIntegerListNull"); + fieldNames.add("fieldShortListNotNull"); + fieldNames.add("fieldShortListNull"); + fieldNames.add("fieldByteListNotNull"); + fieldNames.add("fieldByteListNull"); + fieldNames.add("fieldDoubleListNotNull"); + fieldNames.add("fieldDoubleListNull"); + fieldNames.add("fieldFloatListNotNull"); + fieldNames.add("fieldFloatListNull"); + fieldNames.add("fieldDateListNotNull"); + fieldNames.add("fieldDateListNull"); FIELD_NAMES = Collections.unmodifiableList(fieldNames); } private NullTypesColumnInfo columnInfo; private ProxyState proxyState; + private RealmList fieldStringListNotNullRealmList; + private RealmList fieldStringListNullRealmList; + private RealmList fieldBinaryListNotNullRealmList; + private RealmList fieldBinaryListNullRealmList; + private RealmList fieldBooleanListNotNullRealmList; + private RealmList fieldBooleanListNullRealmList; + private RealmList fieldLongListNotNullRealmList; + private RealmList fieldLongListNullRealmList; + private RealmList fieldIntegerListNotNullRealmList; + private RealmList fieldIntegerListNullRealmList; + private RealmList fieldShortListNotNullRealmList; + private RealmList fieldShortListNullRealmList; + private RealmList fieldByteListNotNullRealmList; + private RealmList fieldByteListNullRealmList; + private RealmList fieldDoubleListNotNullRealmList; + private RealmList fieldDoubleListNullRealmList; + private RealmList fieldFloatListNotNullRealmList; + private RealmList fieldFloatListNullRealmList; + private RealmList fieldDateListNotNullRealmList; + private RealmList fieldDateListNullRealmList; NullTypesRealmProxy() { proxyState.setConstructionFinished(); @@ -823,7 +923,787 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (((RealmObjectProxy) value).realmGet$proxyState().getRealm$realm() != proxyState.getRealm$realm()) { throw new IllegalArgumentException("'value' belongs to a different Realm."); } - proxyState.getRow$realm().setLink(columnInfo.fieldObjectNullIndex, ((RealmObjectProxy)value).realmGet$proxyState().getRow$realm().getIndex()); + proxyState.getRow$realm().setLink(columnInfo.fieldObjectNullIndex, ((RealmObjectProxy) value).realmGet$proxyState().getRow$realm().getIndex()); + } + + @Override + public RealmList realmGet$fieldStringListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldStringListNotNullRealmList != null) { + return fieldStringListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldStringListNotNullIndex); + fieldStringListNotNullRealmList = new RealmList(java.lang.String.class, osList, proxyState.getRealm$realm()); + return fieldStringListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldStringListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldStringListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldStringListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.String item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldStringListNotNull' is not allowed by schema."); + } else { + osList.addString(item); + } + } + } + + @Override + public RealmList realmGet$fieldStringListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldStringListNullRealmList != null) { + return fieldStringListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldStringListNullIndex); + fieldStringListNullRealmList = new RealmList(java.lang.String.class, osList, proxyState.getRealm$realm()); + return fieldStringListNullRealmList; + } + } + + @Override + public void realmSet$fieldStringListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldStringListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldStringListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.String item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addString(item); + } + } + } + + @Override + public RealmList realmGet$fieldBinaryListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldBinaryListNotNullRealmList != null) { + return fieldBinaryListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBinaryListNotNullIndex); + fieldBinaryListNotNullRealmList = new RealmList(byte[].class, osList, proxyState.getRealm$realm()); + return fieldBinaryListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldBinaryListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldBinaryListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBinaryListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (byte[] item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldBinaryListNotNull' is not allowed by schema."); + } else { + osList.addBinary(item); + } + } + } + + @Override + public RealmList realmGet$fieldBinaryListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldBinaryListNullRealmList != null) { + return fieldBinaryListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBinaryListNullIndex); + fieldBinaryListNullRealmList = new RealmList(byte[].class, osList, proxyState.getRealm$realm()); + return fieldBinaryListNullRealmList; + } + } + + @Override + public void realmSet$fieldBinaryListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldBinaryListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBinaryListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (byte[] item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addBinary(item); + } + } + } + + @Override + public RealmList realmGet$fieldBooleanListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldBooleanListNotNullRealmList != null) { + return fieldBooleanListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBooleanListNotNullIndex); + fieldBooleanListNotNullRealmList = new RealmList(java.lang.Boolean.class, osList, proxyState.getRealm$realm()); + return fieldBooleanListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldBooleanListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldBooleanListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBooleanListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Boolean item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldBooleanListNotNull' is not allowed by schema."); + } else { + osList.addBoolean(item); + } + } + } + + @Override + public RealmList realmGet$fieldBooleanListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldBooleanListNullRealmList != null) { + return fieldBooleanListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBooleanListNullIndex); + fieldBooleanListNullRealmList = new RealmList(java.lang.Boolean.class, osList, proxyState.getRealm$realm()); + return fieldBooleanListNullRealmList; + } + } + + @Override + public void realmSet$fieldBooleanListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldBooleanListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBooleanListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Boolean item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addBoolean(item); + } + } + } + + @Override + public RealmList realmGet$fieldLongListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldLongListNotNullRealmList != null) { + return fieldLongListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldLongListNotNullIndex); + fieldLongListNotNullRealmList = new RealmList(java.lang.Long.class, osList, proxyState.getRealm$realm()); + return fieldLongListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldLongListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldLongListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldLongListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Long item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldLongListNotNull' is not allowed by schema."); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$fieldLongListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldLongListNullRealmList != null) { + return fieldLongListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldLongListNullIndex); + fieldLongListNullRealmList = new RealmList(java.lang.Long.class, osList, proxyState.getRealm$realm()); + return fieldLongListNullRealmList; + } + } + + @Override + public void realmSet$fieldLongListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldLongListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldLongListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Long item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$fieldIntegerListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldIntegerListNotNullRealmList != null) { + return fieldIntegerListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldIntegerListNotNullIndex); + fieldIntegerListNotNullRealmList = new RealmList(java.lang.Integer.class, osList, proxyState.getRealm$realm()); + return fieldIntegerListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldIntegerListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldIntegerListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldIntegerListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Integer item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldIntegerListNotNull' is not allowed by schema."); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$fieldIntegerListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldIntegerListNullRealmList != null) { + return fieldIntegerListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldIntegerListNullIndex); + fieldIntegerListNullRealmList = new RealmList(java.lang.Integer.class, osList, proxyState.getRealm$realm()); + return fieldIntegerListNullRealmList; + } + } + + @Override + public void realmSet$fieldIntegerListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldIntegerListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldIntegerListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Integer item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$fieldShortListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldShortListNotNullRealmList != null) { + return fieldShortListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldShortListNotNullIndex); + fieldShortListNotNullRealmList = new RealmList(java.lang.Short.class, osList, proxyState.getRealm$realm()); + return fieldShortListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldShortListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldShortListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldShortListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Short item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldShortListNotNull' is not allowed by schema."); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$fieldShortListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldShortListNullRealmList != null) { + return fieldShortListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldShortListNullIndex); + fieldShortListNullRealmList = new RealmList(java.lang.Short.class, osList, proxyState.getRealm$realm()); + return fieldShortListNullRealmList; + } + } + + @Override + public void realmSet$fieldShortListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldShortListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldShortListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Short item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$fieldByteListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldByteListNotNullRealmList != null) { + return fieldByteListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldByteListNotNullIndex); + fieldByteListNotNullRealmList = new RealmList(java.lang.Byte.class, osList, proxyState.getRealm$realm()); + return fieldByteListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldByteListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldByteListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldByteListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Byte item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldByteListNotNull' is not allowed by schema."); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$fieldByteListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldByteListNullRealmList != null) { + return fieldByteListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldByteListNullIndex); + fieldByteListNullRealmList = new RealmList(java.lang.Byte.class, osList, proxyState.getRealm$realm()); + return fieldByteListNullRealmList; + } + } + + @Override + public void realmSet$fieldByteListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldByteListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldByteListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Byte item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addLong(item.longValue()); + } + } + } + + @Override + public RealmList realmGet$fieldDoubleListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldDoubleListNotNullRealmList != null) { + return fieldDoubleListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDoubleListNotNullIndex); + fieldDoubleListNotNullRealmList = new RealmList(java.lang.Double.class, osList, proxyState.getRealm$realm()); + return fieldDoubleListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldDoubleListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldDoubleListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDoubleListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Double item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldDoubleListNotNull' is not allowed by schema."); + } else { + osList.addDouble(item.doubleValue()); + } + } + } + + @Override + public RealmList realmGet$fieldDoubleListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldDoubleListNullRealmList != null) { + return fieldDoubleListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDoubleListNullIndex); + fieldDoubleListNullRealmList = new RealmList(java.lang.Double.class, osList, proxyState.getRealm$realm()); + return fieldDoubleListNullRealmList; + } + } + + @Override + public void realmSet$fieldDoubleListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldDoubleListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDoubleListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Double item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addDouble(item.doubleValue()); + } + } + } + + @Override + public RealmList realmGet$fieldFloatListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldFloatListNotNullRealmList != null) { + return fieldFloatListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldFloatListNotNullIndex); + fieldFloatListNotNullRealmList = new RealmList(java.lang.Float.class, osList, proxyState.getRealm$realm()); + return fieldFloatListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldFloatListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldFloatListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldFloatListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Float item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldFloatListNotNull' is not allowed by schema."); + } else { + osList.addFloat(item.floatValue()); + } + } + } + + @Override + public RealmList realmGet$fieldFloatListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldFloatListNullRealmList != null) { + return fieldFloatListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldFloatListNullIndex); + fieldFloatListNullRealmList = new RealmList(java.lang.Float.class, osList, proxyState.getRealm$realm()); + return fieldFloatListNullRealmList; + } + } + + @Override + public void realmSet$fieldFloatListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldFloatListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldFloatListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.lang.Float item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addFloat(item.floatValue()); + } + } + } + + @Override + public RealmList realmGet$fieldDateListNotNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldDateListNotNullRealmList != null) { + return fieldDateListNotNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDateListNotNullIndex); + fieldDateListNotNullRealmList = new RealmList(java.util.Date.class, osList, proxyState.getRealm$realm()); + return fieldDateListNotNullRealmList; + } + } + + @Override + public void realmSet$fieldDateListNotNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldDateListNotNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDateListNotNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.util.Date item : value) { + if (item == null) { + throw new IllegalArgumentException("Storing 'null' into fieldDateListNotNull' is not allowed by schema."); + } else { + osList.addDate(item); + } + } + } + + @Override + public RealmList realmGet$fieldDateListNull() { + proxyState.getRealm$realm().checkIfValid(); + // use the cached value if available + if (fieldDateListNullRealmList != null) { + return fieldDateListNullRealmList; + } else { + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDateListNullIndex); + fieldDateListNullRealmList = new RealmList(java.util.Date.class, osList, proxyState.getRealm$realm()); + return fieldDateListNullRealmList; + } + } + + @Override + public void realmSet$fieldDateListNull(RealmList value) { + if (proxyState.isUnderConstruction()) { + if (!proxyState.getAcceptDefaultValue$realm()) { + return; + } + if (proxyState.getExcludeFields$realm().contains("fieldDateListNull")) { + return; + } + } + + proxyState.getRealm$realm().checkIfValid(); + OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDateListNullIndex); + osList.removeAll(); + if (value == null) { + return; + } + for (java.util.Date item : value) { + if (item == null) { + osList.addNull(); + } else { + osList.addDate(item); + } + } } private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { @@ -849,6 +1729,26 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { builder.addPersistedProperty("fieldDateNotNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED); builder.addPersistedProperty("fieldDateNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); builder.addPersistedLinkProperty("fieldObjectNull", RealmFieldType.OBJECT, "NullTypes"); + builder.addPersistedLinkProperty("fieldStringListNotNull", RealmFieldType.LIST, "String"); + builder.addPersistedLinkProperty("fieldStringListNull", RealmFieldType.LIST, "String"); + builder.addPersistedLinkProperty("fieldBinaryListNotNull", RealmFieldType.LIST, "byte[]"); + builder.addPersistedLinkProperty("fieldBinaryListNull", RealmFieldType.LIST, "byte[]"); + builder.addPersistedLinkProperty("fieldBooleanListNotNull", RealmFieldType.LIST, "Boolean"); + builder.addPersistedLinkProperty("fieldBooleanListNull", RealmFieldType.LIST, "Boolean"); + builder.addPersistedLinkProperty("fieldLongListNotNull", RealmFieldType.LIST, "Long"); + builder.addPersistedLinkProperty("fieldLongListNull", RealmFieldType.LIST, "Long"); + builder.addPersistedLinkProperty("fieldIntegerListNotNull", RealmFieldType.LIST, "Integer"); + builder.addPersistedLinkProperty("fieldIntegerListNull", RealmFieldType.LIST, "Integer"); + builder.addPersistedLinkProperty("fieldShortListNotNull", RealmFieldType.LIST, "Short"); + builder.addPersistedLinkProperty("fieldShortListNull", RealmFieldType.LIST, "Short"); + builder.addPersistedLinkProperty("fieldByteListNotNull", RealmFieldType.LIST, "Byte"); + builder.addPersistedLinkProperty("fieldByteListNull", RealmFieldType.LIST, "Byte"); + builder.addPersistedLinkProperty("fieldDoubleListNotNull", RealmFieldType.LIST, "Double"); + builder.addPersistedLinkProperty("fieldDoubleListNull", RealmFieldType.LIST, "Double"); + builder.addPersistedLinkProperty("fieldFloatListNotNull", RealmFieldType.LIST, "Float"); + builder.addPersistedLinkProperty("fieldFloatListNull", RealmFieldType.LIST, "Float"); + builder.addPersistedLinkProperty("fieldDateListNotNull", RealmFieldType.LIST, "Date"); + builder.addPersistedLinkProperty("fieldDateListNull", RealmFieldType.LIST, "Date"); return builder.build(); } @@ -871,11 +1771,72 @@ public static List getFieldNames() { @SuppressWarnings("cast") public static some.test.NullTypes createOrUpdateUsingJsonObject(Realm realm, JSONObject json, boolean update) throws JSONException { - final List excludeFields = new ArrayList(1); + final List excludeFields = new ArrayList(21); if (json.has("fieldObjectNull")) { excludeFields.add("fieldObjectNull"); } + if (json.has("fieldStringListNotNull")) { + excludeFields.add("fieldStringListNotNull"); + } + if (json.has("fieldStringListNull")) { + excludeFields.add("fieldStringListNull"); + } + if (json.has("fieldBinaryListNotNull")) { + excludeFields.add("fieldBinaryListNotNull"); + } + if (json.has("fieldBinaryListNull")) { + excludeFields.add("fieldBinaryListNull"); + } + if (json.has("fieldBooleanListNotNull")) { + excludeFields.add("fieldBooleanListNotNull"); + } + if (json.has("fieldBooleanListNull")) { + excludeFields.add("fieldBooleanListNull"); + } + if (json.has("fieldLongListNotNull")) { + excludeFields.add("fieldLongListNotNull"); + } + if (json.has("fieldLongListNull")) { + excludeFields.add("fieldLongListNull"); + } + if (json.has("fieldIntegerListNotNull")) { + excludeFields.add("fieldIntegerListNotNull"); + } + if (json.has("fieldIntegerListNull")) { + excludeFields.add("fieldIntegerListNull"); + } + if (json.has("fieldShortListNotNull")) { + excludeFields.add("fieldShortListNotNull"); + } + if (json.has("fieldShortListNull")) { + excludeFields.add("fieldShortListNull"); + } + if (json.has("fieldByteListNotNull")) { + excludeFields.add("fieldByteListNotNull"); + } + if (json.has("fieldByteListNull")) { + excludeFields.add("fieldByteListNull"); + } + if (json.has("fieldDoubleListNotNull")) { + excludeFields.add("fieldDoubleListNotNull"); + } + if (json.has("fieldDoubleListNull")) { + excludeFields.add("fieldDoubleListNull"); + } + if (json.has("fieldFloatListNotNull")) { + excludeFields.add("fieldFloatListNotNull"); + } + if (json.has("fieldFloatListNull")) { + excludeFields.add("fieldFloatListNull"); + } + if (json.has("fieldDateListNotNull")) { + excludeFields.add("fieldDateListNotNull"); + } + if (json.has("fieldDateListNull")) { + excludeFields.add("fieldDateListNull"); + } some.test.NullTypes obj = realm.createObjectInternal(some.test.NullTypes.class, true, excludeFields); + final NullTypesRealmProxyInterface objProxy = (NullTypesRealmProxyInterface) obj; if (json.has("fieldStringNotNull")) { if (json.isNull("fieldStringNotNull")) { @@ -1206,6 +2167,26 @@ public static some.test.NullTypes createUsingJsonStream(Realm realm, JsonReader some.test.NullTypes fieldObjectNullObj = NullTypesRealmProxy.createUsingJsonStream(realm, reader); objProxy.realmSet$fieldObjectNull(fieldObjectNullObj); } + } else if (name.equals("fieldStringListNotNull")) { + } else if (name.equals("fieldStringListNull")) { + } else if (name.equals("fieldBinaryListNotNull")) { + } else if (name.equals("fieldBinaryListNull")) { + } else if (name.equals("fieldBooleanListNotNull")) { + } else if (name.equals("fieldBooleanListNull")) { + } else if (name.equals("fieldLongListNotNull")) { + } else if (name.equals("fieldLongListNull")) { + } else if (name.equals("fieldIntegerListNotNull")) { + } else if (name.equals("fieldIntegerListNull")) { + } else if (name.equals("fieldShortListNotNull")) { + } else if (name.equals("fieldShortListNull")) { + } else if (name.equals("fieldByteListNotNull")) { + } else if (name.equals("fieldByteListNull")) { + } else if (name.equals("fieldDoubleListNotNull")) { + } else if (name.equals("fieldDoubleListNull")) { + } else if (name.equals("fieldFloatListNotNull")) { + } else if (name.equals("fieldFloatListNull")) { + } else if (name.equals("fieldDateListNotNull")) { + } else if (name.equals("fieldDateListNull")) { } else { reader.skipValue(); } @@ -1278,6 +2259,26 @@ public static some.test.NullTypes copy(Realm realm, some.test.NullTypes newObjec realmObjectCopy.realmSet$fieldObjectNull(NullTypesRealmProxy.copyOrUpdate(realm, fieldObjectNullObj, update, cache)); } } + realmObjectCopy.realmSet$fieldStringListNotNull(realmObjectSource.realmGet$fieldStringListNotNull()); + realmObjectCopy.realmSet$fieldStringListNull(realmObjectSource.realmGet$fieldStringListNull()); + realmObjectCopy.realmSet$fieldBinaryListNotNull(realmObjectSource.realmGet$fieldBinaryListNotNull()); + realmObjectCopy.realmSet$fieldBinaryListNull(realmObjectSource.realmGet$fieldBinaryListNull()); + realmObjectCopy.realmSet$fieldBooleanListNotNull(realmObjectSource.realmGet$fieldBooleanListNotNull()); + realmObjectCopy.realmSet$fieldBooleanListNull(realmObjectSource.realmGet$fieldBooleanListNull()); + realmObjectCopy.realmSet$fieldLongListNotNull(realmObjectSource.realmGet$fieldLongListNotNull()); + realmObjectCopy.realmSet$fieldLongListNull(realmObjectSource.realmGet$fieldLongListNull()); + realmObjectCopy.realmSet$fieldIntegerListNotNull(realmObjectSource.realmGet$fieldIntegerListNotNull()); + realmObjectCopy.realmSet$fieldIntegerListNull(realmObjectSource.realmGet$fieldIntegerListNull()); + realmObjectCopy.realmSet$fieldShortListNotNull(realmObjectSource.realmGet$fieldShortListNotNull()); + realmObjectCopy.realmSet$fieldShortListNull(realmObjectSource.realmGet$fieldShortListNull()); + realmObjectCopy.realmSet$fieldByteListNotNull(realmObjectSource.realmGet$fieldByteListNotNull()); + realmObjectCopy.realmSet$fieldByteListNull(realmObjectSource.realmGet$fieldByteListNull()); + realmObjectCopy.realmSet$fieldDoubleListNotNull(realmObjectSource.realmGet$fieldDoubleListNotNull()); + realmObjectCopy.realmSet$fieldDoubleListNull(realmObjectSource.realmGet$fieldDoubleListNull()); + realmObjectCopy.realmSet$fieldFloatListNotNull(realmObjectSource.realmGet$fieldFloatListNotNull()); + realmObjectCopy.realmSet$fieldFloatListNull(realmObjectSource.realmGet$fieldFloatListNull()); + realmObjectCopy.realmSet$fieldDateListNotNull(realmObjectSource.realmGet$fieldDateListNotNull()); + realmObjectCopy.realmSet$fieldDateListNull(realmObjectSource.realmGet$fieldDateListNull()); return realmObject; } @@ -1918,6 +2919,86 @@ public String toString() { stringBuilder.append("{fieldObjectNull:"); stringBuilder.append(realmGet$fieldObjectNull() != null ? "NullTypes" : "null"); stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldStringListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldStringListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldStringListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldStringListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldBinaryListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldBinaryListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldBinaryListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldBinaryListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldBooleanListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldBooleanListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldBooleanListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldBooleanListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldLongListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldLongListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldLongListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldLongListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldIntegerListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldIntegerListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldIntegerListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldIntegerListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldShortListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldShortListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldShortListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldShortListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldByteListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldByteListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldByteListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldByteListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldDoubleListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldDoubleListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldDoubleListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldDoubleListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldFloatListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldFloatListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldFloatListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldFloatListNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldDateListNotNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldDateListNotNull().size()).append("]"); + stringBuilder.append("}"); + stringBuilder.append(","); + stringBuilder.append("{fieldDateListNull:"); + stringBuilder.append("RealmList[").append(realmGet$fieldDateListNull().size()).append("]"); + stringBuilder.append("}"); stringBuilder.append("]"); return stringBuilder.toString(); } @@ -1958,5 +3039,4 @@ public boolean equals(Object o) { return true; } - } diff --git a/realm/realm-annotations-processor/src/test/resources/some/test/AllTypes.java b/realm/realm-annotations-processor/src/test/resources/some/test/AllTypes.java index f3d88fc2cb..4539db1355 100644 --- a/realm/realm-annotations-processor/src/test/resources/some/test/AllTypes.java +++ b/realm/realm-annotations-processor/src/test/resources/some/test/AllTypes.java @@ -51,6 +51,18 @@ public class AllTypes extends RealmObject { private RealmList columnRealmList; + private RealmList columnStringList; + private RealmList columnBinaryList; + private RealmList columnBooleanList; + private RealmList columnLongList; + private RealmList columnIntegerList; + private RealmList columnShortList; + private RealmList columnByteList; + private RealmList columnDoubleList; + private RealmList columnFloatList; + private RealmList columnDateList; + + @LinkingObjects(FIELD_PARENTS) private final RealmResults parentObjects = null; diff --git a/realm/realm-annotations-processor/src/test/resources/some/test/NullTypes.java b/realm/realm-annotations-processor/src/test/resources/some/test/NullTypes.java index 1904076340..45bc47aae6 100644 --- a/realm/realm-annotations-processor/src/test/resources/some/test/NullTypes.java +++ b/realm/realm-annotations-processor/src/test/resources/some/test/NullTypes.java @@ -66,6 +66,45 @@ public class NullTypes extends RealmObject { private NullTypes fieldObjectNull; + @Required + private RealmList fieldStringListNotNull; + private RealmList fieldStringListNull; + + @Required + private RealmList fieldBinaryListNotNull; + private RealmList fieldBinaryListNull; + + @Required + private RealmList fieldBooleanListNotNull; + private RealmList fieldBooleanListNull; + + @Required + private RealmList fieldLongListNotNull; + private RealmList fieldLongListNull; + + @Required + private RealmList fieldIntegerListNotNull; + private RealmList fieldIntegerListNull; + + @Required + private RealmList fieldShortListNotNull; + private RealmList fieldShortListNull; + + @Required + private RealmList fieldByteListNotNull; + private RealmList fieldByteListNull; + + @Required + private RealmList fieldDoubleListNotNull; + private RealmList fieldDoubleListNull; + + @Required + private RealmList fieldFloatListNotNull; + private RealmList fieldFloatListNull; + + @Required + private RealmList fieldDateListNotNull; + private RealmList fieldDateListNull; public String getFieldStringNotNull() { return realmGet$fieldStringNotNull(); From c48bee21a7e3f04cc4b2ef9e3ca29ecacc21995a Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 6 Sep 2017 22:43:04 +0900 Subject: [PATCH 06/72] throw an exception if query or aggregation feature is used for primitive list --- .../src/main/java/io/realm/RealmList.java | 88 ++++++++++++------- 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 57e7db922a..123d747e8d 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -59,6 +59,7 @@ public class RealmList extends AbstractList implements OrderedRealmCollect private static final String ONLY_IN_MANAGED_MODE_MESSAGE = "This method is only available in managed mode"; private static final String NULL_OBJECTS_NOT_ALLOWED_MESSAGE = "RealmList does not accept null values"; + private static final String ALLOWED_ONLY_FOR_REALM_MODEL_ELEMENT_MESSAGE = "This feature is available only when the element type is implementing RealmModel"; private static final String INVALID_OBJECT_TYPE_MESSAGE = "Unacceptable value type. Acceptable: %1$s, actual: %2$s"; public static final String REMOVE_OUTSIDE_TRANSACTION_ERROR = "Objects can only be removed from inside a write transaction"; @@ -578,6 +579,9 @@ public int size() { public RealmQuery where() { if (isManaged()) { checkValidRealm(); + if (!osListOperator.forRealmModel()) { + throw new IllegalStateException(ALLOWED_ONLY_FOR_REALM_MODEL_ELEMENT_MESSAGE); + } return RealmQuery.createQueryFromList(this); } else { throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); @@ -590,11 +594,8 @@ public RealmQuery where() { @Override @Nullable public Number min(String fieldName) { - if (isManaged()) { - return this.where().min(fieldName); - } else { - throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); - } + // where() throws if not managed + return where().min(fieldName); } /** @@ -603,11 +604,8 @@ public Number min(String fieldName) { @Override @Nullable public Number max(String fieldName) { - if (isManaged()) { - return this.where().max(fieldName); - } else { - throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); - } + // where() throws if not managed + return this.where().max(fieldName); } /** @@ -615,11 +613,8 @@ public Number max(String fieldName) { */ @Override public Number sum(String fieldName) { - if (isManaged()) { - return this.where().sum(fieldName); - } else { - throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); - } + // where() throws if not managed + return this.where().sum(fieldName); } /** @@ -627,11 +622,8 @@ public Number sum(String fieldName) { */ @Override public double average(String fieldName) { - if (isManaged()) { - return this.where().average(fieldName); - } else { - throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); - } + // where() throws if not managed + return this.where().average(fieldName); } /** @@ -640,11 +632,8 @@ public double average(String fieldName) { @Override @Nullable public Date maxDate(String fieldName) { - if (isManaged()) { - return this.where().maximumDate(fieldName); - } else { - throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); - } + // where() throws if not managed + return this.where().maximumDate(fieldName); } /** @@ -653,11 +642,8 @@ public Date maxDate(String fieldName) { @Override @Nullable public Date minDate(String fieldName) { - if (isManaged()) { - return this.where().minimumDate(fieldName); - } else { - throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); - } + // where() throws if not managed + return this.where().minimumDate(fieldName); } /** @@ -1369,6 +1355,8 @@ private static abstract class ManagedListOperator { this.osList = osList; } + abstract boolean forRealmModel(); + OsList getOsList() { return osList; } @@ -1434,6 +1422,11 @@ private static final class RealmModelListOperator extends ManagedListOperator this.className = className; } + @Override + boolean forRealmModel() { + return true; + } + @Override T get(int index) { //noinspection unchecked @@ -1535,6 +1528,11 @@ private static final class StringListOperator extends ManagedListOperator extends ManagedListOperator { super(realm, osList, clazz); } + @Override + boolean forRealmModel() { + return false; + } + @Nullable @Override T get(int index) { @@ -1682,6 +1685,11 @@ private static final class BooleanListOperator extends ManagedListOperator super(realm, osList, clazz); } + @Override + boolean forRealmModel() { + return false; + } + @Nullable @Override Float get(int index) { @@ -1934,6 +1957,11 @@ private static final class DateListOperator extends ManagedListOperator { super(realm, osList, clazz); } + @Override + boolean forRealmModel() { + return false; + } + @Nullable @Override Date get(int index) { From 86bd3d44261fc86261c4f23fc02e16db4cdb364b Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 6 Sep 2017 23:52:47 +0900 Subject: [PATCH 07/72] fix tests --- .../io/realm/AllTypesRealmProxy.java | 20 +++++----- .../io/realm/NullTypesRealmProxy.java | 40 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index 22aaa3a5f2..ae49e11476 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -871,16 +871,16 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { builder.addPersistedProperty("columnMutableRealmInteger", RealmFieldType.INTEGER, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); builder.addPersistedLinkProperty("columnObject", RealmFieldType.OBJECT, "AllTypes"); builder.addPersistedLinkProperty("columnRealmList", RealmFieldType.LIST, "AllTypes"); - builder.addPersistedLinkProperty("columnStringList", RealmFieldType.LIST, "String"); - builder.addPersistedLinkProperty("columnBinaryList", RealmFieldType.LIST, "byte[]"); - builder.addPersistedLinkProperty("columnBooleanList", RealmFieldType.LIST, "Boolean"); - builder.addPersistedLinkProperty("columnLongList", RealmFieldType.LIST, "Long"); - builder.addPersistedLinkProperty("columnIntegerList", RealmFieldType.LIST, "Integer"); - builder.addPersistedLinkProperty("columnShortList", RealmFieldType.LIST, "Short"); - builder.addPersistedLinkProperty("columnByteList", RealmFieldType.LIST, "Byte"); - builder.addPersistedLinkProperty("columnDoubleList", RealmFieldType.LIST, "Double"); - builder.addPersistedLinkProperty("columnFloatList", RealmFieldType.LIST, "Float"); - builder.addPersistedLinkProperty("columnDateList", RealmFieldType.LIST, "Date"); + builder.addPersistedLinkProperty("columnStringList", RealmFieldType.STRING_LIST, ""); + builder.addPersistedLinkProperty("columnBinaryList", RealmFieldType.BINARY_LIST, ""); + builder.addPersistedLinkProperty("columnBooleanList", RealmFieldType.BOOLEAN_LIST, ""); + builder.addPersistedLinkProperty("columnLongList", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("columnIntegerList", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("columnShortList", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("columnByteList", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("columnDoubleList", RealmFieldType.DOUBLE_LIST, ""); + builder.addPersistedLinkProperty("columnFloatList", RealmFieldType.FLOAT_LIST, ""); + builder.addPersistedLinkProperty("columnDateList", RealmFieldType.DATE_LIST, ""); builder.addComputedLinkProperty("parentObjects", "AllTypes", "columnObject"); return builder.build(); } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index d497fee814..dab0525b0b 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -1729,26 +1729,26 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { builder.addPersistedProperty("fieldDateNotNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED); builder.addPersistedProperty("fieldDateNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); builder.addPersistedLinkProperty("fieldObjectNull", RealmFieldType.OBJECT, "NullTypes"); - builder.addPersistedLinkProperty("fieldStringListNotNull", RealmFieldType.LIST, "String"); - builder.addPersistedLinkProperty("fieldStringListNull", RealmFieldType.LIST, "String"); - builder.addPersistedLinkProperty("fieldBinaryListNotNull", RealmFieldType.LIST, "byte[]"); - builder.addPersistedLinkProperty("fieldBinaryListNull", RealmFieldType.LIST, "byte[]"); - builder.addPersistedLinkProperty("fieldBooleanListNotNull", RealmFieldType.LIST, "Boolean"); - builder.addPersistedLinkProperty("fieldBooleanListNull", RealmFieldType.LIST, "Boolean"); - builder.addPersistedLinkProperty("fieldLongListNotNull", RealmFieldType.LIST, "Long"); - builder.addPersistedLinkProperty("fieldLongListNull", RealmFieldType.LIST, "Long"); - builder.addPersistedLinkProperty("fieldIntegerListNotNull", RealmFieldType.LIST, "Integer"); - builder.addPersistedLinkProperty("fieldIntegerListNull", RealmFieldType.LIST, "Integer"); - builder.addPersistedLinkProperty("fieldShortListNotNull", RealmFieldType.LIST, "Short"); - builder.addPersistedLinkProperty("fieldShortListNull", RealmFieldType.LIST, "Short"); - builder.addPersistedLinkProperty("fieldByteListNotNull", RealmFieldType.LIST, "Byte"); - builder.addPersistedLinkProperty("fieldByteListNull", RealmFieldType.LIST, "Byte"); - builder.addPersistedLinkProperty("fieldDoubleListNotNull", RealmFieldType.LIST, "Double"); - builder.addPersistedLinkProperty("fieldDoubleListNull", RealmFieldType.LIST, "Double"); - builder.addPersistedLinkProperty("fieldFloatListNotNull", RealmFieldType.LIST, "Float"); - builder.addPersistedLinkProperty("fieldFloatListNull", RealmFieldType.LIST, "Float"); - builder.addPersistedLinkProperty("fieldDateListNotNull", RealmFieldType.LIST, "Date"); - builder.addPersistedLinkProperty("fieldDateListNull", RealmFieldType.LIST, "Date"); + builder.addPersistedLinkProperty("fieldStringListNotNull", RealmFieldType.STRING_LIST, ""); + builder.addPersistedLinkProperty("fieldStringListNull", RealmFieldType.STRING_LIST, ""); + builder.addPersistedLinkProperty("fieldBinaryListNotNull", RealmFieldType.BINARY_LIST, ""); + builder.addPersistedLinkProperty("fieldBinaryListNull", RealmFieldType.BINARY_LIST, ""); + builder.addPersistedLinkProperty("fieldBooleanListNotNull", RealmFieldType.BOOLEAN_LIST, ""); + builder.addPersistedLinkProperty("fieldBooleanListNull", RealmFieldType.BOOLEAN_LIST, ""); + builder.addPersistedLinkProperty("fieldLongListNotNull", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("fieldLongListNull", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("fieldIntegerListNotNull", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("fieldIntegerListNull", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("fieldShortListNotNull", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("fieldShortListNull", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("fieldByteListNotNull", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("fieldByteListNull", RealmFieldType.INTEGER_LIST, ""); + builder.addPersistedLinkProperty("fieldDoubleListNotNull", RealmFieldType.DOUBLE_LIST, ""); + builder.addPersistedLinkProperty("fieldDoubleListNull", RealmFieldType.DOUBLE_LIST, ""); + builder.addPersistedLinkProperty("fieldFloatListNotNull", RealmFieldType.FLOAT_LIST, ""); + builder.addPersistedLinkProperty("fieldFloatListNull", RealmFieldType.FLOAT_LIST, ""); + builder.addPersistedLinkProperty("fieldDateListNotNull", RealmFieldType.DATE_LIST, ""); + builder.addPersistedLinkProperty("fieldDateListNull", RealmFieldType.DATE_LIST, ""); return builder.build(); } From 84aca51eec2419be3e8497b2c13bb9b01e9cddd4 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 7 Sep 2017 05:38:58 +0900 Subject: [PATCH 08/72] address findbugs issues --- .../src/main/java/io/realm/RealmList.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 123d747e8d..f668a00fda 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -1433,7 +1433,8 @@ T get(int index) { return (T) realm.get((Class) clazz, className, osList.getUncheckedRow(index)); } - private void checkValidValue(@Nullable Object value) { + @Nonnull + private RealmModel castToNonNullModel(@Nullable Object value) { if (value == null) { throw new IllegalArgumentException(NULL_OBJECTS_NOT_ALLOWED_MESSAGE); } @@ -1443,30 +1444,31 @@ private void checkValidValue(@Nullable Object value) { "java.lang.String", value.getClass().getName())); } + return (RealmModel) value; } @Override - public void add(@SuppressWarnings("NullableProblems") Object value) { - checkValidValue(value); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); + public void add(@Nullable Object value) { + final RealmModel model = castToNonNullModel(value); + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); osList.addRow(proxy.realmGet$proxyState().getRow$realm().getIndex()); } @Override - public void insert(int index, @SuppressWarnings("NullableProblems") Object value) { - checkValidValue(value); + public void insert(int index, @Nullable Object value) { + final RealmModel model = castToNonNullModel(value); checkInsertIndex(index); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); osList.insertRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); } @Override protected T set(int index, @Nullable Object value) { - checkValidValue(value); + final RealmModel model = castToNonNullModel(value); checkElementExists(index); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); //noinspection unchecked final T oldObject = get(index); osList.setRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); From 94b109b7f0c212f2540217e44a9e2c944344febc Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 7 Sep 2017 08:58:21 +0900 Subject: [PATCH 09/72] added Javadoc comment and RealmList.toArray() --- .../src/main/java/io/realm/RealmList.java | 386 ++++++++++++++++++ 1 file changed, 386 insertions(+) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index f668a00fda..cecb300e4a 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -16,6 +16,7 @@ package io.realm; +import java.lang.reflect.Array; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; @@ -1178,8 +1179,205 @@ public void add(@Nullable E e) { } } + @Override + public T[] toArray(T[] a) { + if (!isManaged()) { + return super.toArray(a); + } + + final Class componentType = a.getClass().getComponentType(); + final OsList osList = osListOperator.getOsList(); + final int size = size(); + if (componentType == String.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + for (int i = 0; i < size; i++) { + //noinspection unchecked + a[i] = (T) osListOperator.get(i); + } + return a; + } + + if (componentType == Long.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + if (e == null || e instanceof Long) { + //noinspection unchecked + a[i] = (T) e; + } else { + //noinspection unchecked + a[i] = (T) Long.valueOf(((Number) e).longValue()); + } + } + return a; + } + + if (componentType == Integer.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + + if (e == null || e instanceof Integer) { + //noinspection unchecked + a[i] = null; + } else { + //noinspection unchecked + a[i] = (T) Integer.valueOf(((Number) e).intValue()); + } + } + return a; + } + + if (componentType == Short.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + if (e == null || e instanceof Short) { + //noinspection unchecked + a[i] = null; + } else { + //noinspection unchecked + a[i] = (T) Short.valueOf(((Number) e).shortValue()); + } + } + return a; + } + + if (componentType == Byte.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + if (e == null || e instanceof Byte) { + //noinspection unchecked + a[i] = null; + } else { + //noinspection unchecked + a[i] = (T) Byte.valueOf(((Number) e).byteValue()); + } + } + return a; + } + + if (componentType == Double.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + if (e == null || e instanceof Double) { + //noinspection unchecked + a[i] = null; + } else { + //noinspection unchecked + a[i] = (T) Double.valueOf(((Number) e).doubleValue()); + } + } + return a; + } + + if (componentType == Float.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + if (e == null || e instanceof Float) { + //noinspection unchecked + a[i] = null; + } else { + //noinspection unchecked + a[i] = (T) Float.valueOf(((Number) e).floatValue()); + } + } + return a; + } + + if (componentType == Boolean.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + //noinspection unchecked + a[i] = (T) e; + } + return a; + } + + if (componentType == Date.class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + //noinspection unchecked + a[i] = (T) e; + } + return a; + } + + if (componentType == byte[].class) { + if (a.length < size) { + //noinspection unchecked + a = (T[]) Array.newInstance(componentType, size); + } + + for (int i = 0; i < size; i++) { + final E e = osListOperator.get(i); + //noinspection unchecked + a[i] = (T) e; + } + return a; + } + + return super.toArray(a); + } + + /** + * Returns newly allocated {@code long} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code valueForNull} is used instead. + * + * @return newly allocated {@code long} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toLongArray() + * @see #toArray() + * @see #toArray(Object[]) + */ @SuppressWarnings("WeakerAccess") public long[] toLongArray(@SuppressWarnings("SameParameterValue") long valueForNull) { + if (!isManaged()) { + throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); + } if (clazz == null || Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toLongArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } @@ -1192,12 +1390,41 @@ public long[] toLongArray(@SuppressWarnings("SameParameterValue") long valueForN return result; } + /** + * Returns newly allocated {@code long} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code 0L} is used instead. + * + * @return newly allocated {@code long} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toLongArray(long) + * @see #toArray() + * @see #toArray(Object[]) + */ public long[] toLongArray() { return toLongArray(0L); } + /** + * Returns newly allocated {@code int} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code valueForNull} is used instead. + * + * @return newly allocated {@code int} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toIntArray() + * @see #toArray() + * @see #toArray(Object[]) + */ @SuppressWarnings("WeakerAccess") public int[] toIntArray(@SuppressWarnings("SameParameterValue") int valueForNull) { + if (!isManaged()) { + throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); + } if (clazz == null || Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toIntArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } @@ -1210,12 +1437,41 @@ public int[] toIntArray(@SuppressWarnings("SameParameterValue") int valueForNull return result; } + /** + * Returns newly allocated {@code int} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code 0} is used instead. + * + * @return newly allocated {@code int} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toIntArray(int) + * @see #toArray() + * @see #toArray(Object[]) + */ public int[] toIntArray() { return toIntArray(0); } + /** + * Returns newly allocated {@code short} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code valueForNull} is used instead. + * + * @return newly allocated {@code short} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toShortArray() + * @see #toArray() + * @see #toArray(Object[]) + */ @SuppressWarnings("WeakerAccess") public short[] toShortArray(@SuppressWarnings("SameParameterValue") short valueForNull) { + if (!isManaged()) { + throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); + } if (clazz == null || Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toShortArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } @@ -1228,12 +1484,41 @@ public short[] toShortArray(@SuppressWarnings("SameParameterValue") short valueF return result; } + /** + * Returns newly allocated {@code short} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code (short) 0} is used instead. + * + * @return newly allocated {@code short} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toShortArray(short) + * @see #toArray() + * @see #toArray(Object[]) + */ public short[] toShortArray() { return toShortArray((short) 0); } + /** + * Returns newly allocated {@code byte} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code valueForNull} is used instead. + * + * @return newly allocated {@code byte} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toByteArray() + * @see #toArray() + * @see #toArray(Object[]) + */ @SuppressWarnings("WeakerAccess") public byte[] toByteArray(@SuppressWarnings("SameParameterValue") byte valueForNull) { + if (!isManaged()) { + throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); + } if (clazz == null || Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toByteArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } @@ -1245,12 +1530,42 @@ public byte[] toByteArray(@SuppressWarnings("SameParameterValue") byte valueForN } return result; } + + /** + * Returns newly allocated {@code byte} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code (byte) 0} is used instead. + * + * @return newly allocated {@code byte} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toByteArray(byte) + * @see #toArray() + * @see #toArray(Object[]) + */ public byte[] toByteArray() { return toByteArray((byte) 0); } + /** + * Returns newly allocated {@code boolean} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code valueForNull} is used instead. + * + * @return newly allocated {@code boolean} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toBooleanArray() + * @see #toArray() + * @see #toArray(Object[]) + */ @SuppressWarnings("WeakerAccess") public boolean[] toBooleanArray(@SuppressWarnings("SameParameterValue") boolean valueForNull) { + if (!isManaged()) { + throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); + } if (clazz != Boolean.class) { throw new IllegalStateException("toBooleanArray() is only supported when the element type is 'java.lang.Boolean'."); } @@ -1263,12 +1578,41 @@ public boolean[] toBooleanArray(@SuppressWarnings("SameParameterValue") boolean return result; } + /** + * Returns newly allocated {@code boolean} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code false} is used instead. + * + * @return newly allocated {@code boolean} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toBooleanArray(boolean) + * @see #toArray() + * @see #toArray(Object[]) + */ public boolean[] toBooleanArray() { return toBooleanArray(false); } + /** + * Returns newly allocated {@code double} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code valueForNull} is used instead. + * + * @return newly allocated {@code double} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toDoubleArray() + * @see #toArray() + * @see #toArray(Object[]) + */ @SuppressWarnings("WeakerAccess") public double[] toDoubleArray(@SuppressWarnings("SameParameterValue") double valueForNull) { + if (!isManaged()) { + throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); + } if (clazz == null || Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toDoubleArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } @@ -1282,12 +1626,41 @@ public double[] toDoubleArray(@SuppressWarnings("SameParameterValue") double val return result; } + /** + * Returns newly allocated {@code double} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code 0D} is used instead. + * + * @return newly allocated {@code double} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toDoubleArray(double) + * @see #toArray() + * @see #toArray(Object[]) + */ public double[] toDoubleArray() { return toDoubleArray(0D); } + /** + * Returns newly allocated {@code float} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code valueForNull} is used instead. + * + * @return newly allocated {@code float} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toFloatArray() + * @see #toArray() + * @see #toArray(Object[]) + */ @SuppressWarnings("WeakerAccess") public float[] toFloatArray(@SuppressWarnings("SameParameterValue") float valueForNull) { + if (!isManaged()) { + throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); + } if (clazz == null || Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toFloatArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } @@ -1301,6 +1674,19 @@ public float[] toFloatArray(@SuppressWarnings("SameParameterValue") float valueF return result; } + /** + * Returns newly allocated {@code float} array that contains all values in this {@link RealmList}. + *

+ * This method is available only when the list is managed and the element type is implementing {@link Number} interface. + *

+ * If this list contains {@code null} value, {@code 0F} is used instead. + * + * @return newly allocated {@code float} array. + * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. + * @see #toFloatArray(float) + * @see #toArray() + * @see #toArray(Object[]) + */ public float[] toFloatArray() { return toFloatArray(0F); } From 04c04c1017b5fe9e7f24588e1058cdb108a90e4b Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 7 Sep 2017 09:21:30 +0900 Subject: [PATCH 10/72] fix bug --- .../main/java/io/realm/processor/RealmProxyClassGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index f5fde5520d..67a5ff4e43 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -1486,7 +1486,7 @@ private void emitCopyMethod(JavaWriter writer) throws IOException { .endControlFlow() .emitEmptyLine(); - } else if (Utils.isRealmModelList(field)) { + } else if (Utils.isRealmValueList(field)) { // FIXME need to implement logic for value list fields. } else if (Utils.isMutableRealmInteger(field)) { From c1d23965fd5ddc76f2fb7a1a0c47afeaadb002e4 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 7 Sep 2017 14:44:49 +0900 Subject: [PATCH 11/72] implement Primitive List logic for copy() and insert() --- .../processor/RealmProxyClassGenerator.java | 21 +- .../io/realm/AllTypesRealmProxy.java | 120 +++++++++ .../io/realm/NullTypesRealmProxy.java | 240 ++++++++++++++++++ 3 files changed, 377 insertions(+), 4 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 67a5ff4e43..e9cd0a9b82 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -1080,8 +1080,22 @@ private void emitInsertMethod(JavaWriter writer) throws IOException { .endControlFlow() .endControlFlow(); } else if (Utils.isRealmValueList(field)) { - // FIXME need to implement logic for value list fields. - + final String genericType = Utils.getGenericTypeQualifiedName(field); + final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + writer + .emitEmptyLine() + .emitStatement("RealmList<%s> %sList = ((%s) object).%s()", + genericType, fieldName, interfaceName, getter) + .beginControlFlow("if (%sList != null)", fieldName) + .emitStatement("OsList %1$sOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.%1$sIndex)", fieldName) + .beginControlFlow("for (%1$s %2$sItem : %2$sList)", genericType, fieldName) + .beginControlFlow("if (%1$sItem == null)", fieldName) + .emitStatement(fieldName + "OsList.addNull()") + .nextControlFlow("else") + .emitStatement(getStatementForAppendingValueToOsList(fieldName + "OsList", fieldName + "Item", elementTypeMirror)) + .endControlFlow() + .endControlFlow() + .endControlFlow(); } else { if (metadata.getPrimaryKey() != field) { setTableValues(writer, fieldType, fieldName, interfaceName, getter, false); @@ -1487,8 +1501,7 @@ private void emitCopyMethod(JavaWriter writer) throws IOException { .emitEmptyLine(); } else if (Utils.isRealmValueList(field)) { - // FIXME need to implement logic for value list fields. - + writer.emitStatement("realmObjectCopy.%s(realmObjectSource.%s())", setter, getter); } else if (Utils.isMutableRealmInteger(field)) { writer.emitEmptyLine() .emitStatement("realmObjectCopy.%1$s().set(realmObjectSource.%1$s().get())", getter); diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index ae49e11476..07272e72e8 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -1327,6 +1327,126 @@ public static long insert(Realm realm, some.test.AllTypes object, Map columnStringListList = ((AllTypesRealmProxyInterface) object).realmGet$columnStringList(); + if (columnStringListList != null) { + OsList columnStringListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnStringListIndex); + for (java.lang.String columnStringListItem : columnStringListList) { + if (columnStringListItem == null) { + columnStringListOsList.addNull(); + } else { + columnStringListOsList.addString(columnStringListItem); + } + } + } + + RealmList columnBinaryListList = ((AllTypesRealmProxyInterface) object).realmGet$columnBinaryList(); + if (columnBinaryListList != null) { + OsList columnBinaryListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnBinaryListIndex); + for (byte[] columnBinaryListItem : columnBinaryListList) { + if (columnBinaryListItem == null) { + columnBinaryListOsList.addNull(); + } else { + columnBinaryListOsList.addBinary(columnBinaryListItem); + } + } + } + + RealmList columnBooleanListList = ((AllTypesRealmProxyInterface) object).realmGet$columnBooleanList(); + if (columnBooleanListList != null) { + OsList columnBooleanListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnBooleanListIndex); + for (java.lang.Boolean columnBooleanListItem : columnBooleanListList) { + if (columnBooleanListItem == null) { + columnBooleanListOsList.addNull(); + } else { + columnBooleanListOsList.addBoolean(columnBooleanListItem); + } + } + } + + RealmList columnLongListList = ((AllTypesRealmProxyInterface) object).realmGet$columnLongList(); + if (columnLongListList != null) { + OsList columnLongListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnLongListIndex); + for (java.lang.Long columnLongListItem : columnLongListList) { + if (columnLongListItem == null) { + columnLongListOsList.addNull(); + } else { + columnLongListOsList.addLong(columnLongListItem.longValue()); + } + } + } + + RealmList columnIntegerListList = ((AllTypesRealmProxyInterface) object).realmGet$columnIntegerList(); + if (columnIntegerListList != null) { + OsList columnIntegerListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnIntegerListIndex); + for (java.lang.Integer columnIntegerListItem : columnIntegerListList) { + if (columnIntegerListItem == null) { + columnIntegerListOsList.addNull(); + } else { + columnIntegerListOsList.addLong(columnIntegerListItem.longValue()); + } + } + } + + RealmList columnShortListList = ((AllTypesRealmProxyInterface) object).realmGet$columnShortList(); + if (columnShortListList != null) { + OsList columnShortListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnShortListIndex); + for (java.lang.Short columnShortListItem : columnShortListList) { + if (columnShortListItem == null) { + columnShortListOsList.addNull(); + } else { + columnShortListOsList.addLong(columnShortListItem.longValue()); + } + } + } + + RealmList columnByteListList = ((AllTypesRealmProxyInterface) object).realmGet$columnByteList(); + if (columnByteListList != null) { + OsList columnByteListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnByteListIndex); + for (java.lang.Byte columnByteListItem : columnByteListList) { + if (columnByteListItem == null) { + columnByteListOsList.addNull(); + } else { + columnByteListOsList.addLong(columnByteListItem.longValue()); + } + } + } + + RealmList columnDoubleListList = ((AllTypesRealmProxyInterface) object).realmGet$columnDoubleList(); + if (columnDoubleListList != null) { + OsList columnDoubleListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnDoubleListIndex); + for (java.lang.Double columnDoubleListItem : columnDoubleListList) { + if (columnDoubleListItem == null) { + columnDoubleListOsList.addNull(); + } else { + columnDoubleListOsList.addDouble(columnDoubleListItem.doubleValue()); + } + } + } + + RealmList columnFloatListList = ((AllTypesRealmProxyInterface) object).realmGet$columnFloatList(); + if (columnFloatListList != null) { + OsList columnFloatListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnFloatListIndex); + for (java.lang.Float columnFloatListItem : columnFloatListList) { + if (columnFloatListItem == null) { + columnFloatListOsList.addNull(); + } else { + columnFloatListOsList.addFloat(columnFloatListItem.floatValue()); + } + } + } + + RealmList columnDateListList = ((AllTypesRealmProxyInterface) object).realmGet$columnDateList(); + if (columnDateListList != null) { + OsList columnDateListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnDateListIndex); + for (java.util.Date columnDateListItem : columnDateListList) { + if (columnDateListItem == null) { + columnDateListOsList.addNull(); + } else { + columnDateListOsList.addDate(columnDateListItem); + } + } + } return rowIndex; } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index dab0525b0b..a4b9e29cc1 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -2380,6 +2380,246 @@ public static long insert(Realm realm, some.test.NullTypes object, Map fieldStringListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldStringListNotNull(); + if (fieldStringListNotNullList != null) { + OsList fieldStringListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldStringListNotNullIndex); + for (java.lang.String fieldStringListNotNullItem : fieldStringListNotNullList) { + if (fieldStringListNotNullItem == null) { + fieldStringListNotNullOsList.addNull(); + } else { + fieldStringListNotNullOsList.addString(fieldStringListNotNullItem); + } + } + } + + RealmList fieldStringListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldStringListNull(); + if (fieldStringListNullList != null) { + OsList fieldStringListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldStringListNullIndex); + for (java.lang.String fieldStringListNullItem : fieldStringListNullList) { + if (fieldStringListNullItem == null) { + fieldStringListNullOsList.addNull(); + } else { + fieldStringListNullOsList.addString(fieldStringListNullItem); + } + } + } + + RealmList fieldBinaryListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBinaryListNotNull(); + if (fieldBinaryListNotNullList != null) { + OsList fieldBinaryListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBinaryListNotNullIndex); + for (byte[] fieldBinaryListNotNullItem : fieldBinaryListNotNullList) { + if (fieldBinaryListNotNullItem == null) { + fieldBinaryListNotNullOsList.addNull(); + } else { + fieldBinaryListNotNullOsList.addBinary(fieldBinaryListNotNullItem); + } + } + } + + RealmList fieldBinaryListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBinaryListNull(); + if (fieldBinaryListNullList != null) { + OsList fieldBinaryListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBinaryListNullIndex); + for (byte[] fieldBinaryListNullItem : fieldBinaryListNullList) { + if (fieldBinaryListNullItem == null) { + fieldBinaryListNullOsList.addNull(); + } else { + fieldBinaryListNullOsList.addBinary(fieldBinaryListNullItem); + } + } + } + + RealmList fieldBooleanListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBooleanListNotNull(); + if (fieldBooleanListNotNullList != null) { + OsList fieldBooleanListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBooleanListNotNullIndex); + for (java.lang.Boolean fieldBooleanListNotNullItem : fieldBooleanListNotNullList) { + if (fieldBooleanListNotNullItem == null) { + fieldBooleanListNotNullOsList.addNull(); + } else { + fieldBooleanListNotNullOsList.addBoolean(fieldBooleanListNotNullItem); + } + } + } + + RealmList fieldBooleanListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBooleanListNull(); + if (fieldBooleanListNullList != null) { + OsList fieldBooleanListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBooleanListNullIndex); + for (java.lang.Boolean fieldBooleanListNullItem : fieldBooleanListNullList) { + if (fieldBooleanListNullItem == null) { + fieldBooleanListNullOsList.addNull(); + } else { + fieldBooleanListNullOsList.addBoolean(fieldBooleanListNullItem); + } + } + } + + RealmList fieldLongListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldLongListNotNull(); + if (fieldLongListNotNullList != null) { + OsList fieldLongListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldLongListNotNullIndex); + for (java.lang.Long fieldLongListNotNullItem : fieldLongListNotNullList) { + if (fieldLongListNotNullItem == null) { + fieldLongListNotNullOsList.addNull(); + } else { + fieldLongListNotNullOsList.addLong(fieldLongListNotNullItem.longValue()); + } + } + } + + RealmList fieldLongListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldLongListNull(); + if (fieldLongListNullList != null) { + OsList fieldLongListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldLongListNullIndex); + for (java.lang.Long fieldLongListNullItem : fieldLongListNullList) { + if (fieldLongListNullItem == null) { + fieldLongListNullOsList.addNull(); + } else { + fieldLongListNullOsList.addLong(fieldLongListNullItem.longValue()); + } + } + } + + RealmList fieldIntegerListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldIntegerListNotNull(); + if (fieldIntegerListNotNullList != null) { + OsList fieldIntegerListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldIntegerListNotNullIndex); + for (java.lang.Integer fieldIntegerListNotNullItem : fieldIntegerListNotNullList) { + if (fieldIntegerListNotNullItem == null) { + fieldIntegerListNotNullOsList.addNull(); + } else { + fieldIntegerListNotNullOsList.addLong(fieldIntegerListNotNullItem.longValue()); + } + } + } + + RealmList fieldIntegerListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldIntegerListNull(); + if (fieldIntegerListNullList != null) { + OsList fieldIntegerListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldIntegerListNullIndex); + for (java.lang.Integer fieldIntegerListNullItem : fieldIntegerListNullList) { + if (fieldIntegerListNullItem == null) { + fieldIntegerListNullOsList.addNull(); + } else { + fieldIntegerListNullOsList.addLong(fieldIntegerListNullItem.longValue()); + } + } + } + + RealmList fieldShortListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldShortListNotNull(); + if (fieldShortListNotNullList != null) { + OsList fieldShortListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldShortListNotNullIndex); + for (java.lang.Short fieldShortListNotNullItem : fieldShortListNotNullList) { + if (fieldShortListNotNullItem == null) { + fieldShortListNotNullOsList.addNull(); + } else { + fieldShortListNotNullOsList.addLong(fieldShortListNotNullItem.longValue()); + } + } + } + + RealmList fieldShortListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldShortListNull(); + if (fieldShortListNullList != null) { + OsList fieldShortListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldShortListNullIndex); + for (java.lang.Short fieldShortListNullItem : fieldShortListNullList) { + if (fieldShortListNullItem == null) { + fieldShortListNullOsList.addNull(); + } else { + fieldShortListNullOsList.addLong(fieldShortListNullItem.longValue()); + } + } + } + + RealmList fieldByteListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldByteListNotNull(); + if (fieldByteListNotNullList != null) { + OsList fieldByteListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldByteListNotNullIndex); + for (java.lang.Byte fieldByteListNotNullItem : fieldByteListNotNullList) { + if (fieldByteListNotNullItem == null) { + fieldByteListNotNullOsList.addNull(); + } else { + fieldByteListNotNullOsList.addLong(fieldByteListNotNullItem.longValue()); + } + } + } + + RealmList fieldByteListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldByteListNull(); + if (fieldByteListNullList != null) { + OsList fieldByteListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldByteListNullIndex); + for (java.lang.Byte fieldByteListNullItem : fieldByteListNullList) { + if (fieldByteListNullItem == null) { + fieldByteListNullOsList.addNull(); + } else { + fieldByteListNullOsList.addLong(fieldByteListNullItem.longValue()); + } + } + } + + RealmList fieldDoubleListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDoubleListNotNull(); + if (fieldDoubleListNotNullList != null) { + OsList fieldDoubleListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDoubleListNotNullIndex); + for (java.lang.Double fieldDoubleListNotNullItem : fieldDoubleListNotNullList) { + if (fieldDoubleListNotNullItem == null) { + fieldDoubleListNotNullOsList.addNull(); + } else { + fieldDoubleListNotNullOsList.addDouble(fieldDoubleListNotNullItem.doubleValue()); + } + } + } + + RealmList fieldDoubleListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDoubleListNull(); + if (fieldDoubleListNullList != null) { + OsList fieldDoubleListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDoubleListNullIndex); + for (java.lang.Double fieldDoubleListNullItem : fieldDoubleListNullList) { + if (fieldDoubleListNullItem == null) { + fieldDoubleListNullOsList.addNull(); + } else { + fieldDoubleListNullOsList.addDouble(fieldDoubleListNullItem.doubleValue()); + } + } + } + + RealmList fieldFloatListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldFloatListNotNull(); + if (fieldFloatListNotNullList != null) { + OsList fieldFloatListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldFloatListNotNullIndex); + for (java.lang.Float fieldFloatListNotNullItem : fieldFloatListNotNullList) { + if (fieldFloatListNotNullItem == null) { + fieldFloatListNotNullOsList.addNull(); + } else { + fieldFloatListNotNullOsList.addFloat(fieldFloatListNotNullItem.floatValue()); + } + } + } + + RealmList fieldFloatListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldFloatListNull(); + if (fieldFloatListNullList != null) { + OsList fieldFloatListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldFloatListNullIndex); + for (java.lang.Float fieldFloatListNullItem : fieldFloatListNullList) { + if (fieldFloatListNullItem == null) { + fieldFloatListNullOsList.addNull(); + } else { + fieldFloatListNullOsList.addFloat(fieldFloatListNullItem.floatValue()); + } + } + } + + RealmList fieldDateListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDateListNotNull(); + if (fieldDateListNotNullList != null) { + OsList fieldDateListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDateListNotNullIndex); + for (java.util.Date fieldDateListNotNullItem : fieldDateListNotNullList) { + if (fieldDateListNotNullItem == null) { + fieldDateListNotNullOsList.addNull(); + } else { + fieldDateListNotNullOsList.addDate(fieldDateListNotNullItem); + } + } + } + + RealmList fieldDateListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDateListNull(); + if (fieldDateListNullList != null) { + OsList fieldDateListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDateListNullIndex); + for (java.util.Date fieldDateListNullItem : fieldDateListNullList) { + if (fieldDateListNullItem == null) { + fieldDateListNullOsList.addNull(); + } else { + fieldDateListNullOsList.addDate(fieldDateListNullItem); + } + } + } return rowIndex; } From 5243cd64dc40aecb4b26a22a7665d4c4e98328f1 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 7 Sep 2017 15:18:30 +0900 Subject: [PATCH 12/72] implement Primitive List logic for insert(Realm, Iterator,...) --- .../processor/RealmProxyClassGenerator.java | 18 +- .../io/realm/AllTypesRealmProxy.java | 120 +++++++++ .../io/realm/NullTypesRealmProxy.java | 240 ++++++++++++++++++ 3 files changed, 376 insertions(+), 2 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index e9cd0a9b82..45cede5210 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -1177,8 +1177,22 @@ private void emitInsertListMethod(JavaWriter writer) throws IOException { .endControlFlow(); } else if (Utils.isRealmValueList(field)) { - // FIXME need to implement logic for value list fields. - + final String genericType = Utils.getGenericTypeQualifiedName(field); + final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + writer + .emitEmptyLine() + .emitStatement("RealmList<%s> %sList = ((%s) object).%s()", + genericType, fieldName, interfaceName, getter) + .beginControlFlow("if (%sList != null)", fieldName) + .emitStatement("OsList %1$sOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.%1$sIndex)", fieldName) + .beginControlFlow("for (%1$s %2$sItem : %2$sList)", genericType, fieldName) + .beginControlFlow("if (%1$sItem == null)", fieldName) + .emitStatement(fieldName + "OsList.addNull()") + .nextControlFlow("else") + .emitStatement(getStatementForAppendingValueToOsList(fieldName + "OsList", fieldName + "Item", elementTypeMirror)) + .endControlFlow() + .endControlFlow() + .endControlFlow(); } else { if (metadata.getPrimaryKey() != field) { setTableValues(writer, fieldType, fieldName, interfaceName, getter, false); diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index 07272e72e8..ce3385df53 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -1515,6 +1515,126 @@ public static void insert(Realm realm, Iterator objects, M columnRealmListOsList.addRow(cacheItemIndexcolumnRealmList); } } + + RealmList columnStringListList = ((AllTypesRealmProxyInterface) object).realmGet$columnStringList(); + if (columnStringListList != null) { + OsList columnStringListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnStringListIndex); + for (java.lang.String columnStringListItem : columnStringListList) { + if (columnStringListItem == null) { + columnStringListOsList.addNull(); + } else { + columnStringListOsList.addString(columnStringListItem); + } + } + } + + RealmList columnBinaryListList = ((AllTypesRealmProxyInterface) object).realmGet$columnBinaryList(); + if (columnBinaryListList != null) { + OsList columnBinaryListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnBinaryListIndex); + for (byte[] columnBinaryListItem : columnBinaryListList) { + if (columnBinaryListItem == null) { + columnBinaryListOsList.addNull(); + } else { + columnBinaryListOsList.addBinary(columnBinaryListItem); + } + } + } + + RealmList columnBooleanListList = ((AllTypesRealmProxyInterface) object).realmGet$columnBooleanList(); + if (columnBooleanListList != null) { + OsList columnBooleanListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnBooleanListIndex); + for (java.lang.Boolean columnBooleanListItem : columnBooleanListList) { + if (columnBooleanListItem == null) { + columnBooleanListOsList.addNull(); + } else { + columnBooleanListOsList.addBoolean(columnBooleanListItem); + } + } + } + + RealmList columnLongListList = ((AllTypesRealmProxyInterface) object).realmGet$columnLongList(); + if (columnLongListList != null) { + OsList columnLongListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnLongListIndex); + for (java.lang.Long columnLongListItem : columnLongListList) { + if (columnLongListItem == null) { + columnLongListOsList.addNull(); + } else { + columnLongListOsList.addLong(columnLongListItem.longValue()); + } + } + } + + RealmList columnIntegerListList = ((AllTypesRealmProxyInterface) object).realmGet$columnIntegerList(); + if (columnIntegerListList != null) { + OsList columnIntegerListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnIntegerListIndex); + for (java.lang.Integer columnIntegerListItem : columnIntegerListList) { + if (columnIntegerListItem == null) { + columnIntegerListOsList.addNull(); + } else { + columnIntegerListOsList.addLong(columnIntegerListItem.longValue()); + } + } + } + + RealmList columnShortListList = ((AllTypesRealmProxyInterface) object).realmGet$columnShortList(); + if (columnShortListList != null) { + OsList columnShortListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnShortListIndex); + for (java.lang.Short columnShortListItem : columnShortListList) { + if (columnShortListItem == null) { + columnShortListOsList.addNull(); + } else { + columnShortListOsList.addLong(columnShortListItem.longValue()); + } + } + } + + RealmList columnByteListList = ((AllTypesRealmProxyInterface) object).realmGet$columnByteList(); + if (columnByteListList != null) { + OsList columnByteListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnByteListIndex); + for (java.lang.Byte columnByteListItem : columnByteListList) { + if (columnByteListItem == null) { + columnByteListOsList.addNull(); + } else { + columnByteListOsList.addLong(columnByteListItem.longValue()); + } + } + } + + RealmList columnDoubleListList = ((AllTypesRealmProxyInterface) object).realmGet$columnDoubleList(); + if (columnDoubleListList != null) { + OsList columnDoubleListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnDoubleListIndex); + for (java.lang.Double columnDoubleListItem : columnDoubleListList) { + if (columnDoubleListItem == null) { + columnDoubleListOsList.addNull(); + } else { + columnDoubleListOsList.addDouble(columnDoubleListItem.doubleValue()); + } + } + } + + RealmList columnFloatListList = ((AllTypesRealmProxyInterface) object).realmGet$columnFloatList(); + if (columnFloatListList != null) { + OsList columnFloatListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnFloatListIndex); + for (java.lang.Float columnFloatListItem : columnFloatListList) { + if (columnFloatListItem == null) { + columnFloatListOsList.addNull(); + } else { + columnFloatListOsList.addFloat(columnFloatListItem.floatValue()); + } + } + } + + RealmList columnDateListList = ((AllTypesRealmProxyInterface) object).realmGet$columnDateList(); + if (columnDateListList != null) { + OsList columnDateListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnDateListIndex); + for (java.util.Date columnDateListItem : columnDateListList) { + if (columnDateListItem == null) { + columnDateListOsList.addNull(); + } else { + columnDateListOsList.addDate(columnDateListItem); + } + } + } } } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index a4b9e29cc1..635b15ee3e 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -2728,6 +2728,246 @@ public static void insert(Realm realm, Iterator objects, M } table.setLink(columnInfo.fieldObjectNullIndex, rowIndex, cachefieldObjectNull, false); } + + RealmList fieldStringListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldStringListNotNull(); + if (fieldStringListNotNullList != null) { + OsList fieldStringListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldStringListNotNullIndex); + for (java.lang.String fieldStringListNotNullItem : fieldStringListNotNullList) { + if (fieldStringListNotNullItem == null) { + fieldStringListNotNullOsList.addNull(); + } else { + fieldStringListNotNullOsList.addString(fieldStringListNotNullItem); + } + } + } + + RealmList fieldStringListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldStringListNull(); + if (fieldStringListNullList != null) { + OsList fieldStringListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldStringListNullIndex); + for (java.lang.String fieldStringListNullItem : fieldStringListNullList) { + if (fieldStringListNullItem == null) { + fieldStringListNullOsList.addNull(); + } else { + fieldStringListNullOsList.addString(fieldStringListNullItem); + } + } + } + + RealmList fieldBinaryListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBinaryListNotNull(); + if (fieldBinaryListNotNullList != null) { + OsList fieldBinaryListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBinaryListNotNullIndex); + for (byte[] fieldBinaryListNotNullItem : fieldBinaryListNotNullList) { + if (fieldBinaryListNotNullItem == null) { + fieldBinaryListNotNullOsList.addNull(); + } else { + fieldBinaryListNotNullOsList.addBinary(fieldBinaryListNotNullItem); + } + } + } + + RealmList fieldBinaryListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBinaryListNull(); + if (fieldBinaryListNullList != null) { + OsList fieldBinaryListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBinaryListNullIndex); + for (byte[] fieldBinaryListNullItem : fieldBinaryListNullList) { + if (fieldBinaryListNullItem == null) { + fieldBinaryListNullOsList.addNull(); + } else { + fieldBinaryListNullOsList.addBinary(fieldBinaryListNullItem); + } + } + } + + RealmList fieldBooleanListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBooleanListNotNull(); + if (fieldBooleanListNotNullList != null) { + OsList fieldBooleanListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBooleanListNotNullIndex); + for (java.lang.Boolean fieldBooleanListNotNullItem : fieldBooleanListNotNullList) { + if (fieldBooleanListNotNullItem == null) { + fieldBooleanListNotNullOsList.addNull(); + } else { + fieldBooleanListNotNullOsList.addBoolean(fieldBooleanListNotNullItem); + } + } + } + + RealmList fieldBooleanListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBooleanListNull(); + if (fieldBooleanListNullList != null) { + OsList fieldBooleanListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBooleanListNullIndex); + for (java.lang.Boolean fieldBooleanListNullItem : fieldBooleanListNullList) { + if (fieldBooleanListNullItem == null) { + fieldBooleanListNullOsList.addNull(); + } else { + fieldBooleanListNullOsList.addBoolean(fieldBooleanListNullItem); + } + } + } + + RealmList fieldLongListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldLongListNotNull(); + if (fieldLongListNotNullList != null) { + OsList fieldLongListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldLongListNotNullIndex); + for (java.lang.Long fieldLongListNotNullItem : fieldLongListNotNullList) { + if (fieldLongListNotNullItem == null) { + fieldLongListNotNullOsList.addNull(); + } else { + fieldLongListNotNullOsList.addLong(fieldLongListNotNullItem.longValue()); + } + } + } + + RealmList fieldLongListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldLongListNull(); + if (fieldLongListNullList != null) { + OsList fieldLongListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldLongListNullIndex); + for (java.lang.Long fieldLongListNullItem : fieldLongListNullList) { + if (fieldLongListNullItem == null) { + fieldLongListNullOsList.addNull(); + } else { + fieldLongListNullOsList.addLong(fieldLongListNullItem.longValue()); + } + } + } + + RealmList fieldIntegerListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldIntegerListNotNull(); + if (fieldIntegerListNotNullList != null) { + OsList fieldIntegerListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldIntegerListNotNullIndex); + for (java.lang.Integer fieldIntegerListNotNullItem : fieldIntegerListNotNullList) { + if (fieldIntegerListNotNullItem == null) { + fieldIntegerListNotNullOsList.addNull(); + } else { + fieldIntegerListNotNullOsList.addLong(fieldIntegerListNotNullItem.longValue()); + } + } + } + + RealmList fieldIntegerListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldIntegerListNull(); + if (fieldIntegerListNullList != null) { + OsList fieldIntegerListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldIntegerListNullIndex); + for (java.lang.Integer fieldIntegerListNullItem : fieldIntegerListNullList) { + if (fieldIntegerListNullItem == null) { + fieldIntegerListNullOsList.addNull(); + } else { + fieldIntegerListNullOsList.addLong(fieldIntegerListNullItem.longValue()); + } + } + } + + RealmList fieldShortListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldShortListNotNull(); + if (fieldShortListNotNullList != null) { + OsList fieldShortListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldShortListNotNullIndex); + for (java.lang.Short fieldShortListNotNullItem : fieldShortListNotNullList) { + if (fieldShortListNotNullItem == null) { + fieldShortListNotNullOsList.addNull(); + } else { + fieldShortListNotNullOsList.addLong(fieldShortListNotNullItem.longValue()); + } + } + } + + RealmList fieldShortListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldShortListNull(); + if (fieldShortListNullList != null) { + OsList fieldShortListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldShortListNullIndex); + for (java.lang.Short fieldShortListNullItem : fieldShortListNullList) { + if (fieldShortListNullItem == null) { + fieldShortListNullOsList.addNull(); + } else { + fieldShortListNullOsList.addLong(fieldShortListNullItem.longValue()); + } + } + } + + RealmList fieldByteListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldByteListNotNull(); + if (fieldByteListNotNullList != null) { + OsList fieldByteListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldByteListNotNullIndex); + for (java.lang.Byte fieldByteListNotNullItem : fieldByteListNotNullList) { + if (fieldByteListNotNullItem == null) { + fieldByteListNotNullOsList.addNull(); + } else { + fieldByteListNotNullOsList.addLong(fieldByteListNotNullItem.longValue()); + } + } + } + + RealmList fieldByteListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldByteListNull(); + if (fieldByteListNullList != null) { + OsList fieldByteListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldByteListNullIndex); + for (java.lang.Byte fieldByteListNullItem : fieldByteListNullList) { + if (fieldByteListNullItem == null) { + fieldByteListNullOsList.addNull(); + } else { + fieldByteListNullOsList.addLong(fieldByteListNullItem.longValue()); + } + } + } + + RealmList fieldDoubleListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDoubleListNotNull(); + if (fieldDoubleListNotNullList != null) { + OsList fieldDoubleListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDoubleListNotNullIndex); + for (java.lang.Double fieldDoubleListNotNullItem : fieldDoubleListNotNullList) { + if (fieldDoubleListNotNullItem == null) { + fieldDoubleListNotNullOsList.addNull(); + } else { + fieldDoubleListNotNullOsList.addDouble(fieldDoubleListNotNullItem.doubleValue()); + } + } + } + + RealmList fieldDoubleListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDoubleListNull(); + if (fieldDoubleListNullList != null) { + OsList fieldDoubleListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDoubleListNullIndex); + for (java.lang.Double fieldDoubleListNullItem : fieldDoubleListNullList) { + if (fieldDoubleListNullItem == null) { + fieldDoubleListNullOsList.addNull(); + } else { + fieldDoubleListNullOsList.addDouble(fieldDoubleListNullItem.doubleValue()); + } + } + } + + RealmList fieldFloatListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldFloatListNotNull(); + if (fieldFloatListNotNullList != null) { + OsList fieldFloatListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldFloatListNotNullIndex); + for (java.lang.Float fieldFloatListNotNullItem : fieldFloatListNotNullList) { + if (fieldFloatListNotNullItem == null) { + fieldFloatListNotNullOsList.addNull(); + } else { + fieldFloatListNotNullOsList.addFloat(fieldFloatListNotNullItem.floatValue()); + } + } + } + + RealmList fieldFloatListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldFloatListNull(); + if (fieldFloatListNullList != null) { + OsList fieldFloatListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldFloatListNullIndex); + for (java.lang.Float fieldFloatListNullItem : fieldFloatListNullList) { + if (fieldFloatListNullItem == null) { + fieldFloatListNullOsList.addNull(); + } else { + fieldFloatListNullOsList.addFloat(fieldFloatListNullItem.floatValue()); + } + } + } + + RealmList fieldDateListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDateListNotNull(); + if (fieldDateListNotNullList != null) { + OsList fieldDateListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDateListNotNullIndex); + for (java.util.Date fieldDateListNotNullItem : fieldDateListNotNullList) { + if (fieldDateListNotNullItem == null) { + fieldDateListNotNullOsList.addNull(); + } else { + fieldDateListNotNullOsList.addDate(fieldDateListNotNullItem); + } + } + } + + RealmList fieldDateListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDateListNull(); + if (fieldDateListNullList != null) { + OsList fieldDateListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDateListNullIndex); + for (java.util.Date fieldDateListNullItem : fieldDateListNullList) { + if (fieldDateListNullItem == null) { + fieldDateListNullOsList.addNull(); + } else { + fieldDateListNullOsList.addDate(fieldDateListNullItem); + } + } + } } } From 7cc7ae557f73a0ca388eb6604e6727a5dceaab45 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 7 Sep 2017 16:08:31 +0900 Subject: [PATCH 13/72] generate code for primitive list in update(), insertOrUpdate() --- .../processor/RealmProxyClassGenerator.java | 46 +- .../io/realm/AllTypesRealmProxy.java | 290 +++++++++ .../io/realm/NullTypesRealmProxy.java | 560 ++++++++++++++++++ 3 files changed, 889 insertions(+), 7 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 45cede5210..458b298fae 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -1187,7 +1187,7 @@ private void emitInsertListMethod(JavaWriter writer) throws IOException { .emitStatement("OsList %1$sOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.%1$sIndex)", fieldName) .beginControlFlow("for (%1$s %2$sItem : %2$sList)", genericType, fieldName) .beginControlFlow("if (%1$sItem == null)", fieldName) - .emitStatement(fieldName + "OsList.addNull()") + .emitStatement("%1$sOsList.addNull()", fieldName) .nextControlFlow("else") .emitStatement(getStatementForAppendingValueToOsList(fieldName + "OsList", fieldName + "Item", elementTypeMirror)) .endControlFlow() @@ -1272,8 +1272,24 @@ private void emitInsertOrUpdateMethod(JavaWriter writer) throws IOException { .emitEmptyLine(); } else if (Utils.isRealmValueList(field)) { - // FIXME need to implement logic for value list fields. - + final String genericType = Utils.getGenericTypeQualifiedName(field); + final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + writer + .emitEmptyLine() + .emitStatement("OsList %1$sOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.%1$sIndex)", fieldName) + .emitStatement("%1$sOsList.removeAll()", fieldName) + .emitStatement("RealmList<%s> %sList = ((%s) object).%s()", + genericType, fieldName, interfaceName, getter) + .beginControlFlow("if (%sList != null)", fieldName) + .beginControlFlow("for (%1$s %2$sItem : %2$sList)", genericType, fieldName) + .beginControlFlow("if (%1$sItem == null)", fieldName) + .emitStatement("%1$sOsList.addNull()", fieldName) + .nextControlFlow("else") + .emitStatement(getStatementForAppendingValueToOsList(fieldName + "OsList", fieldName + "Item", elementTypeMirror)) + .endControlFlow() + .endControlFlow() + .endControlFlow() + .emitEmptyLine(); } else { if (metadata.getPrimaryKey() != field) { setTableValues(writer, fieldType, fieldName, interfaceName, getter, true); @@ -1359,8 +1375,25 @@ private void emitInsertOrUpdateListMethod(JavaWriter writer) throws IOException .emitEmptyLine(); } else if (Utils.isRealmValueList(field)) { - // FIXME need to implement logic for value list fields. - + final String genericType = Utils.getGenericTypeQualifiedName(field); + final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + writer + .emitEmptyLine() + .emitStatement("OsList %1$sOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.%1$sIndex)", fieldName) + .emitStatement("%1$sOsList.removeAll()", fieldName) + .emitStatement("RealmList<%s> %sList = ((%s) object).%s()", + genericType, fieldName, interfaceName, getter) + .beginControlFlow("if (%sList != null)", fieldName) + .beginControlFlow("for (%1$s %2$sItem : %2$sList)", genericType, fieldName) + .beginControlFlow("if (%1$sItem == null)", fieldName) + .emitStatement("%1$sOsList.addNull()", fieldName) + .nextControlFlow("else") + .emitStatement(getStatementForAppendingValueToOsList(fieldName + "OsList", + fieldName + "Item", elementTypeMirror)) + .endControlFlow() + .endControlFlow() + .endControlFlow() + .emitEmptyLine(); } else { if (metadata.getPrimaryKey() != field) { setTableValues(writer, fieldType, fieldName, interfaceName, getter, true); @@ -1664,8 +1697,7 @@ private void emitUpdateMethod(JavaWriter writer) throws IOException { .endControlFlow(); } else if (Utils.isRealmValueList(field)) { - // FIXME need to implement logic for value list fields. - + writer.emitStatement("realmObjectTarget.%s(realmObjectSource.%s())", setter, getter); } else if (Utils.isMutableRealmInteger(field)) { writer.emitStatement("realmObjectTarget.%s().set(realmObjectSource.%s().get())", getter, getter); } else { diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index ce3385df53..b0316135c1 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -1704,6 +1704,146 @@ public static long insertOrUpdate(Realm realm, some.test.AllTypes object, Map columnStringListList = ((AllTypesRealmProxyInterface) object).realmGet$columnStringList(); + if (columnStringListList != null) { + for (java.lang.String columnStringListItem : columnStringListList) { + if (columnStringListItem == null) { + columnStringListOsList.addNull(); + } else { + columnStringListOsList.addString(columnStringListItem); + } + } + } + + + OsList columnBinaryListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnBinaryListIndex); + columnBinaryListOsList.removeAll(); + RealmList columnBinaryListList = ((AllTypesRealmProxyInterface) object).realmGet$columnBinaryList(); + if (columnBinaryListList != null) { + for (byte[] columnBinaryListItem : columnBinaryListList) { + if (columnBinaryListItem == null) { + columnBinaryListOsList.addNull(); + } else { + columnBinaryListOsList.addBinary(columnBinaryListItem); + } + } + } + + + OsList columnBooleanListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnBooleanListIndex); + columnBooleanListOsList.removeAll(); + RealmList columnBooleanListList = ((AllTypesRealmProxyInterface) object).realmGet$columnBooleanList(); + if (columnBooleanListList != null) { + for (java.lang.Boolean columnBooleanListItem : columnBooleanListList) { + if (columnBooleanListItem == null) { + columnBooleanListOsList.addNull(); + } else { + columnBooleanListOsList.addBoolean(columnBooleanListItem); + } + } + } + + + OsList columnLongListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnLongListIndex); + columnLongListOsList.removeAll(); + RealmList columnLongListList = ((AllTypesRealmProxyInterface) object).realmGet$columnLongList(); + if (columnLongListList != null) { + for (java.lang.Long columnLongListItem : columnLongListList) { + if (columnLongListItem == null) { + columnLongListOsList.addNull(); + } else { + columnLongListOsList.addLong(columnLongListItem.longValue()); + } + } + } + + + OsList columnIntegerListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnIntegerListIndex); + columnIntegerListOsList.removeAll(); + RealmList columnIntegerListList = ((AllTypesRealmProxyInterface) object).realmGet$columnIntegerList(); + if (columnIntegerListList != null) { + for (java.lang.Integer columnIntegerListItem : columnIntegerListList) { + if (columnIntegerListItem == null) { + columnIntegerListOsList.addNull(); + } else { + columnIntegerListOsList.addLong(columnIntegerListItem.longValue()); + } + } + } + + + OsList columnShortListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnShortListIndex); + columnShortListOsList.removeAll(); + RealmList columnShortListList = ((AllTypesRealmProxyInterface) object).realmGet$columnShortList(); + if (columnShortListList != null) { + for (java.lang.Short columnShortListItem : columnShortListList) { + if (columnShortListItem == null) { + columnShortListOsList.addNull(); + } else { + columnShortListOsList.addLong(columnShortListItem.longValue()); + } + } + } + + + OsList columnByteListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnByteListIndex); + columnByteListOsList.removeAll(); + RealmList columnByteListList = ((AllTypesRealmProxyInterface) object).realmGet$columnByteList(); + if (columnByteListList != null) { + for (java.lang.Byte columnByteListItem : columnByteListList) { + if (columnByteListItem == null) { + columnByteListOsList.addNull(); + } else { + columnByteListOsList.addLong(columnByteListItem.longValue()); + } + } + } + + + OsList columnDoubleListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnDoubleListIndex); + columnDoubleListOsList.removeAll(); + RealmList columnDoubleListList = ((AllTypesRealmProxyInterface) object).realmGet$columnDoubleList(); + if (columnDoubleListList != null) { + for (java.lang.Double columnDoubleListItem : columnDoubleListList) { + if (columnDoubleListItem == null) { + columnDoubleListOsList.addNull(); + } else { + columnDoubleListOsList.addDouble(columnDoubleListItem.doubleValue()); + } + } + } + + + OsList columnFloatListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnFloatListIndex); + columnFloatListOsList.removeAll(); + RealmList columnFloatListList = ((AllTypesRealmProxyInterface) object).realmGet$columnFloatList(); + if (columnFloatListList != null) { + for (java.lang.Float columnFloatListItem : columnFloatListList) { + if (columnFloatListItem == null) { + columnFloatListOsList.addNull(); + } else { + columnFloatListOsList.addFloat(columnFloatListItem.floatValue()); + } + } + } + + + OsList columnDateListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnDateListIndex); + columnDateListOsList.removeAll(); + RealmList columnDateListList = ((AllTypesRealmProxyInterface) object).realmGet$columnDateList(); + if (columnDateListList != null) { + for (java.util.Date columnDateListItem : columnDateListList) { + if (columnDateListItem == null) { + columnDateListOsList.addNull(); + } else { + columnDateListOsList.addDate(columnDateListItem); + } + } + } + return rowIndex; } @@ -1780,6 +1920,146 @@ public static void insertOrUpdate(Realm realm, Iterator ob } } + + OsList columnStringListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnStringListIndex); + columnStringListOsList.removeAll(); + RealmList columnStringListList = ((AllTypesRealmProxyInterface) object).realmGet$columnStringList(); + if (columnStringListList != null) { + for (java.lang.String columnStringListItem : columnStringListList) { + if (columnStringListItem == null) { + columnStringListOsList.addNull(); + } else { + columnStringListOsList.addString(columnStringListItem); + } + } + } + + + OsList columnBinaryListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnBinaryListIndex); + columnBinaryListOsList.removeAll(); + RealmList columnBinaryListList = ((AllTypesRealmProxyInterface) object).realmGet$columnBinaryList(); + if (columnBinaryListList != null) { + for (byte[] columnBinaryListItem : columnBinaryListList) { + if (columnBinaryListItem == null) { + columnBinaryListOsList.addNull(); + } else { + columnBinaryListOsList.addBinary(columnBinaryListItem); + } + } + } + + + OsList columnBooleanListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnBooleanListIndex); + columnBooleanListOsList.removeAll(); + RealmList columnBooleanListList = ((AllTypesRealmProxyInterface) object).realmGet$columnBooleanList(); + if (columnBooleanListList != null) { + for (java.lang.Boolean columnBooleanListItem : columnBooleanListList) { + if (columnBooleanListItem == null) { + columnBooleanListOsList.addNull(); + } else { + columnBooleanListOsList.addBoolean(columnBooleanListItem); + } + } + } + + + OsList columnLongListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnLongListIndex); + columnLongListOsList.removeAll(); + RealmList columnLongListList = ((AllTypesRealmProxyInterface) object).realmGet$columnLongList(); + if (columnLongListList != null) { + for (java.lang.Long columnLongListItem : columnLongListList) { + if (columnLongListItem == null) { + columnLongListOsList.addNull(); + } else { + columnLongListOsList.addLong(columnLongListItem.longValue()); + } + } + } + + + OsList columnIntegerListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnIntegerListIndex); + columnIntegerListOsList.removeAll(); + RealmList columnIntegerListList = ((AllTypesRealmProxyInterface) object).realmGet$columnIntegerList(); + if (columnIntegerListList != null) { + for (java.lang.Integer columnIntegerListItem : columnIntegerListList) { + if (columnIntegerListItem == null) { + columnIntegerListOsList.addNull(); + } else { + columnIntegerListOsList.addLong(columnIntegerListItem.longValue()); + } + } + } + + + OsList columnShortListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnShortListIndex); + columnShortListOsList.removeAll(); + RealmList columnShortListList = ((AllTypesRealmProxyInterface) object).realmGet$columnShortList(); + if (columnShortListList != null) { + for (java.lang.Short columnShortListItem : columnShortListList) { + if (columnShortListItem == null) { + columnShortListOsList.addNull(); + } else { + columnShortListOsList.addLong(columnShortListItem.longValue()); + } + } + } + + + OsList columnByteListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnByteListIndex); + columnByteListOsList.removeAll(); + RealmList columnByteListList = ((AllTypesRealmProxyInterface) object).realmGet$columnByteList(); + if (columnByteListList != null) { + for (java.lang.Byte columnByteListItem : columnByteListList) { + if (columnByteListItem == null) { + columnByteListOsList.addNull(); + } else { + columnByteListOsList.addLong(columnByteListItem.longValue()); + } + } + } + + + OsList columnDoubleListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnDoubleListIndex); + columnDoubleListOsList.removeAll(); + RealmList columnDoubleListList = ((AllTypesRealmProxyInterface) object).realmGet$columnDoubleList(); + if (columnDoubleListList != null) { + for (java.lang.Double columnDoubleListItem : columnDoubleListList) { + if (columnDoubleListItem == null) { + columnDoubleListOsList.addNull(); + } else { + columnDoubleListOsList.addDouble(columnDoubleListItem.doubleValue()); + } + } + } + + + OsList columnFloatListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnFloatListIndex); + columnFloatListOsList.removeAll(); + RealmList columnFloatListList = ((AllTypesRealmProxyInterface) object).realmGet$columnFloatList(); + if (columnFloatListList != null) { + for (java.lang.Float columnFloatListItem : columnFloatListList) { + if (columnFloatListItem == null) { + columnFloatListOsList.addNull(); + } else { + columnFloatListOsList.addFloat(columnFloatListItem.floatValue()); + } + } + } + + + OsList columnDateListOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.columnDateListIndex); + columnDateListOsList.removeAll(); + RealmList columnDateListList = ((AllTypesRealmProxyInterface) object).realmGet$columnDateList(); + if (columnDateListList != null) { + for (java.util.Date columnDateListItem : columnDateListList) { + if (columnDateListItem == null) { + columnDateListOsList.addNull(); + } else { + columnDateListOsList.addDate(columnDateListItem); + } + } + } + } } @@ -1866,6 +2146,16 @@ static some.test.AllTypes update(Realm realm, some.test.AllTypes realmObject, so } } } + realmObjectTarget.realmSet$columnStringList(realmObjectSource.realmGet$columnStringList()); + realmObjectTarget.realmSet$columnBinaryList(realmObjectSource.realmGet$columnBinaryList()); + realmObjectTarget.realmSet$columnBooleanList(realmObjectSource.realmGet$columnBooleanList()); + realmObjectTarget.realmSet$columnLongList(realmObjectSource.realmGet$columnLongList()); + realmObjectTarget.realmSet$columnIntegerList(realmObjectSource.realmGet$columnIntegerList()); + realmObjectTarget.realmSet$columnShortList(realmObjectSource.realmGet$columnShortList()); + realmObjectTarget.realmSet$columnByteList(realmObjectSource.realmGet$columnByteList()); + realmObjectTarget.realmSet$columnDoubleList(realmObjectSource.realmGet$columnDoubleList()); + realmObjectTarget.realmSet$columnFloatList(realmObjectSource.realmGet$columnFloatList()); + realmObjectTarget.realmSet$columnDateList(realmObjectSource.realmGet$columnDateList()); return realmObject; } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index 635b15ee3e..266667fd83 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -3111,6 +3111,286 @@ public static long insertOrUpdate(Realm realm, some.test.NullTypes object, Map fieldStringListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldStringListNotNull(); + if (fieldStringListNotNullList != null) { + for (java.lang.String fieldStringListNotNullItem : fieldStringListNotNullList) { + if (fieldStringListNotNullItem == null) { + fieldStringListNotNullOsList.addNull(); + } else { + fieldStringListNotNullOsList.addString(fieldStringListNotNullItem); + } + } + } + + + OsList fieldStringListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldStringListNullIndex); + fieldStringListNullOsList.removeAll(); + RealmList fieldStringListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldStringListNull(); + if (fieldStringListNullList != null) { + for (java.lang.String fieldStringListNullItem : fieldStringListNullList) { + if (fieldStringListNullItem == null) { + fieldStringListNullOsList.addNull(); + } else { + fieldStringListNullOsList.addString(fieldStringListNullItem); + } + } + } + + + OsList fieldBinaryListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBinaryListNotNullIndex); + fieldBinaryListNotNullOsList.removeAll(); + RealmList fieldBinaryListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBinaryListNotNull(); + if (fieldBinaryListNotNullList != null) { + for (byte[] fieldBinaryListNotNullItem : fieldBinaryListNotNullList) { + if (fieldBinaryListNotNullItem == null) { + fieldBinaryListNotNullOsList.addNull(); + } else { + fieldBinaryListNotNullOsList.addBinary(fieldBinaryListNotNullItem); + } + } + } + + + OsList fieldBinaryListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBinaryListNullIndex); + fieldBinaryListNullOsList.removeAll(); + RealmList fieldBinaryListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBinaryListNull(); + if (fieldBinaryListNullList != null) { + for (byte[] fieldBinaryListNullItem : fieldBinaryListNullList) { + if (fieldBinaryListNullItem == null) { + fieldBinaryListNullOsList.addNull(); + } else { + fieldBinaryListNullOsList.addBinary(fieldBinaryListNullItem); + } + } + } + + + OsList fieldBooleanListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBooleanListNotNullIndex); + fieldBooleanListNotNullOsList.removeAll(); + RealmList fieldBooleanListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBooleanListNotNull(); + if (fieldBooleanListNotNullList != null) { + for (java.lang.Boolean fieldBooleanListNotNullItem : fieldBooleanListNotNullList) { + if (fieldBooleanListNotNullItem == null) { + fieldBooleanListNotNullOsList.addNull(); + } else { + fieldBooleanListNotNullOsList.addBoolean(fieldBooleanListNotNullItem); + } + } + } + + + OsList fieldBooleanListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBooleanListNullIndex); + fieldBooleanListNullOsList.removeAll(); + RealmList fieldBooleanListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBooleanListNull(); + if (fieldBooleanListNullList != null) { + for (java.lang.Boolean fieldBooleanListNullItem : fieldBooleanListNullList) { + if (fieldBooleanListNullItem == null) { + fieldBooleanListNullOsList.addNull(); + } else { + fieldBooleanListNullOsList.addBoolean(fieldBooleanListNullItem); + } + } + } + + + OsList fieldLongListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldLongListNotNullIndex); + fieldLongListNotNullOsList.removeAll(); + RealmList fieldLongListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldLongListNotNull(); + if (fieldLongListNotNullList != null) { + for (java.lang.Long fieldLongListNotNullItem : fieldLongListNotNullList) { + if (fieldLongListNotNullItem == null) { + fieldLongListNotNullOsList.addNull(); + } else { + fieldLongListNotNullOsList.addLong(fieldLongListNotNullItem.longValue()); + } + } + } + + + OsList fieldLongListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldLongListNullIndex); + fieldLongListNullOsList.removeAll(); + RealmList fieldLongListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldLongListNull(); + if (fieldLongListNullList != null) { + for (java.lang.Long fieldLongListNullItem : fieldLongListNullList) { + if (fieldLongListNullItem == null) { + fieldLongListNullOsList.addNull(); + } else { + fieldLongListNullOsList.addLong(fieldLongListNullItem.longValue()); + } + } + } + + + OsList fieldIntegerListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldIntegerListNotNullIndex); + fieldIntegerListNotNullOsList.removeAll(); + RealmList fieldIntegerListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldIntegerListNotNull(); + if (fieldIntegerListNotNullList != null) { + for (java.lang.Integer fieldIntegerListNotNullItem : fieldIntegerListNotNullList) { + if (fieldIntegerListNotNullItem == null) { + fieldIntegerListNotNullOsList.addNull(); + } else { + fieldIntegerListNotNullOsList.addLong(fieldIntegerListNotNullItem.longValue()); + } + } + } + + + OsList fieldIntegerListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldIntegerListNullIndex); + fieldIntegerListNullOsList.removeAll(); + RealmList fieldIntegerListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldIntegerListNull(); + if (fieldIntegerListNullList != null) { + for (java.lang.Integer fieldIntegerListNullItem : fieldIntegerListNullList) { + if (fieldIntegerListNullItem == null) { + fieldIntegerListNullOsList.addNull(); + } else { + fieldIntegerListNullOsList.addLong(fieldIntegerListNullItem.longValue()); + } + } + } + + + OsList fieldShortListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldShortListNotNullIndex); + fieldShortListNotNullOsList.removeAll(); + RealmList fieldShortListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldShortListNotNull(); + if (fieldShortListNotNullList != null) { + for (java.lang.Short fieldShortListNotNullItem : fieldShortListNotNullList) { + if (fieldShortListNotNullItem == null) { + fieldShortListNotNullOsList.addNull(); + } else { + fieldShortListNotNullOsList.addLong(fieldShortListNotNullItem.longValue()); + } + } + } + + + OsList fieldShortListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldShortListNullIndex); + fieldShortListNullOsList.removeAll(); + RealmList fieldShortListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldShortListNull(); + if (fieldShortListNullList != null) { + for (java.lang.Short fieldShortListNullItem : fieldShortListNullList) { + if (fieldShortListNullItem == null) { + fieldShortListNullOsList.addNull(); + } else { + fieldShortListNullOsList.addLong(fieldShortListNullItem.longValue()); + } + } + } + + + OsList fieldByteListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldByteListNotNullIndex); + fieldByteListNotNullOsList.removeAll(); + RealmList fieldByteListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldByteListNotNull(); + if (fieldByteListNotNullList != null) { + for (java.lang.Byte fieldByteListNotNullItem : fieldByteListNotNullList) { + if (fieldByteListNotNullItem == null) { + fieldByteListNotNullOsList.addNull(); + } else { + fieldByteListNotNullOsList.addLong(fieldByteListNotNullItem.longValue()); + } + } + } + + + OsList fieldByteListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldByteListNullIndex); + fieldByteListNullOsList.removeAll(); + RealmList fieldByteListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldByteListNull(); + if (fieldByteListNullList != null) { + for (java.lang.Byte fieldByteListNullItem : fieldByteListNullList) { + if (fieldByteListNullItem == null) { + fieldByteListNullOsList.addNull(); + } else { + fieldByteListNullOsList.addLong(fieldByteListNullItem.longValue()); + } + } + } + + + OsList fieldDoubleListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDoubleListNotNullIndex); + fieldDoubleListNotNullOsList.removeAll(); + RealmList fieldDoubleListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDoubleListNotNull(); + if (fieldDoubleListNotNullList != null) { + for (java.lang.Double fieldDoubleListNotNullItem : fieldDoubleListNotNullList) { + if (fieldDoubleListNotNullItem == null) { + fieldDoubleListNotNullOsList.addNull(); + } else { + fieldDoubleListNotNullOsList.addDouble(fieldDoubleListNotNullItem.doubleValue()); + } + } + } + + + OsList fieldDoubleListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDoubleListNullIndex); + fieldDoubleListNullOsList.removeAll(); + RealmList fieldDoubleListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDoubleListNull(); + if (fieldDoubleListNullList != null) { + for (java.lang.Double fieldDoubleListNullItem : fieldDoubleListNullList) { + if (fieldDoubleListNullItem == null) { + fieldDoubleListNullOsList.addNull(); + } else { + fieldDoubleListNullOsList.addDouble(fieldDoubleListNullItem.doubleValue()); + } + } + } + + + OsList fieldFloatListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldFloatListNotNullIndex); + fieldFloatListNotNullOsList.removeAll(); + RealmList fieldFloatListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldFloatListNotNull(); + if (fieldFloatListNotNullList != null) { + for (java.lang.Float fieldFloatListNotNullItem : fieldFloatListNotNullList) { + if (fieldFloatListNotNullItem == null) { + fieldFloatListNotNullOsList.addNull(); + } else { + fieldFloatListNotNullOsList.addFloat(fieldFloatListNotNullItem.floatValue()); + } + } + } + + + OsList fieldFloatListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldFloatListNullIndex); + fieldFloatListNullOsList.removeAll(); + RealmList fieldFloatListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldFloatListNull(); + if (fieldFloatListNullList != null) { + for (java.lang.Float fieldFloatListNullItem : fieldFloatListNullList) { + if (fieldFloatListNullItem == null) { + fieldFloatListNullOsList.addNull(); + } else { + fieldFloatListNullOsList.addFloat(fieldFloatListNullItem.floatValue()); + } + } + } + + + OsList fieldDateListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDateListNotNullIndex); + fieldDateListNotNullOsList.removeAll(); + RealmList fieldDateListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDateListNotNull(); + if (fieldDateListNotNullList != null) { + for (java.util.Date fieldDateListNotNullItem : fieldDateListNotNullList) { + if (fieldDateListNotNullItem == null) { + fieldDateListNotNullOsList.addNull(); + } else { + fieldDateListNotNullOsList.addDate(fieldDateListNotNullItem); + } + } + } + + + OsList fieldDateListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDateListNullIndex); + fieldDateListNullOsList.removeAll(); + RealmList fieldDateListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDateListNull(); + if (fieldDateListNullList != null) { + for (java.util.Date fieldDateListNullItem : fieldDateListNullList) { + if (fieldDateListNullItem == null) { + fieldDateListNullOsList.addNull(); + } else { + fieldDateListNullOsList.addDate(fieldDateListNullItem); + } + } + } + return rowIndex; } @@ -3261,6 +3541,286 @@ public static void insertOrUpdate(Realm realm, Iterator ob } else { Table.nativeNullifyLink(tableNativePtr, columnInfo.fieldObjectNullIndex, rowIndex); } + + OsList fieldStringListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldStringListNotNullIndex); + fieldStringListNotNullOsList.removeAll(); + RealmList fieldStringListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldStringListNotNull(); + if (fieldStringListNotNullList != null) { + for (java.lang.String fieldStringListNotNullItem : fieldStringListNotNullList) { + if (fieldStringListNotNullItem == null) { + fieldStringListNotNullOsList.addNull(); + } else { + fieldStringListNotNullOsList.addString(fieldStringListNotNullItem); + } + } + } + + + OsList fieldStringListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldStringListNullIndex); + fieldStringListNullOsList.removeAll(); + RealmList fieldStringListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldStringListNull(); + if (fieldStringListNullList != null) { + for (java.lang.String fieldStringListNullItem : fieldStringListNullList) { + if (fieldStringListNullItem == null) { + fieldStringListNullOsList.addNull(); + } else { + fieldStringListNullOsList.addString(fieldStringListNullItem); + } + } + } + + + OsList fieldBinaryListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBinaryListNotNullIndex); + fieldBinaryListNotNullOsList.removeAll(); + RealmList fieldBinaryListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBinaryListNotNull(); + if (fieldBinaryListNotNullList != null) { + for (byte[] fieldBinaryListNotNullItem : fieldBinaryListNotNullList) { + if (fieldBinaryListNotNullItem == null) { + fieldBinaryListNotNullOsList.addNull(); + } else { + fieldBinaryListNotNullOsList.addBinary(fieldBinaryListNotNullItem); + } + } + } + + + OsList fieldBinaryListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBinaryListNullIndex); + fieldBinaryListNullOsList.removeAll(); + RealmList fieldBinaryListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBinaryListNull(); + if (fieldBinaryListNullList != null) { + for (byte[] fieldBinaryListNullItem : fieldBinaryListNullList) { + if (fieldBinaryListNullItem == null) { + fieldBinaryListNullOsList.addNull(); + } else { + fieldBinaryListNullOsList.addBinary(fieldBinaryListNullItem); + } + } + } + + + OsList fieldBooleanListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBooleanListNotNullIndex); + fieldBooleanListNotNullOsList.removeAll(); + RealmList fieldBooleanListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBooleanListNotNull(); + if (fieldBooleanListNotNullList != null) { + for (java.lang.Boolean fieldBooleanListNotNullItem : fieldBooleanListNotNullList) { + if (fieldBooleanListNotNullItem == null) { + fieldBooleanListNotNullOsList.addNull(); + } else { + fieldBooleanListNotNullOsList.addBoolean(fieldBooleanListNotNullItem); + } + } + } + + + OsList fieldBooleanListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldBooleanListNullIndex); + fieldBooleanListNullOsList.removeAll(); + RealmList fieldBooleanListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldBooleanListNull(); + if (fieldBooleanListNullList != null) { + for (java.lang.Boolean fieldBooleanListNullItem : fieldBooleanListNullList) { + if (fieldBooleanListNullItem == null) { + fieldBooleanListNullOsList.addNull(); + } else { + fieldBooleanListNullOsList.addBoolean(fieldBooleanListNullItem); + } + } + } + + + OsList fieldLongListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldLongListNotNullIndex); + fieldLongListNotNullOsList.removeAll(); + RealmList fieldLongListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldLongListNotNull(); + if (fieldLongListNotNullList != null) { + for (java.lang.Long fieldLongListNotNullItem : fieldLongListNotNullList) { + if (fieldLongListNotNullItem == null) { + fieldLongListNotNullOsList.addNull(); + } else { + fieldLongListNotNullOsList.addLong(fieldLongListNotNullItem.longValue()); + } + } + } + + + OsList fieldLongListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldLongListNullIndex); + fieldLongListNullOsList.removeAll(); + RealmList fieldLongListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldLongListNull(); + if (fieldLongListNullList != null) { + for (java.lang.Long fieldLongListNullItem : fieldLongListNullList) { + if (fieldLongListNullItem == null) { + fieldLongListNullOsList.addNull(); + } else { + fieldLongListNullOsList.addLong(fieldLongListNullItem.longValue()); + } + } + } + + + OsList fieldIntegerListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldIntegerListNotNullIndex); + fieldIntegerListNotNullOsList.removeAll(); + RealmList fieldIntegerListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldIntegerListNotNull(); + if (fieldIntegerListNotNullList != null) { + for (java.lang.Integer fieldIntegerListNotNullItem : fieldIntegerListNotNullList) { + if (fieldIntegerListNotNullItem == null) { + fieldIntegerListNotNullOsList.addNull(); + } else { + fieldIntegerListNotNullOsList.addLong(fieldIntegerListNotNullItem.longValue()); + } + } + } + + + OsList fieldIntegerListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldIntegerListNullIndex); + fieldIntegerListNullOsList.removeAll(); + RealmList fieldIntegerListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldIntegerListNull(); + if (fieldIntegerListNullList != null) { + for (java.lang.Integer fieldIntegerListNullItem : fieldIntegerListNullList) { + if (fieldIntegerListNullItem == null) { + fieldIntegerListNullOsList.addNull(); + } else { + fieldIntegerListNullOsList.addLong(fieldIntegerListNullItem.longValue()); + } + } + } + + + OsList fieldShortListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldShortListNotNullIndex); + fieldShortListNotNullOsList.removeAll(); + RealmList fieldShortListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldShortListNotNull(); + if (fieldShortListNotNullList != null) { + for (java.lang.Short fieldShortListNotNullItem : fieldShortListNotNullList) { + if (fieldShortListNotNullItem == null) { + fieldShortListNotNullOsList.addNull(); + } else { + fieldShortListNotNullOsList.addLong(fieldShortListNotNullItem.longValue()); + } + } + } + + + OsList fieldShortListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldShortListNullIndex); + fieldShortListNullOsList.removeAll(); + RealmList fieldShortListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldShortListNull(); + if (fieldShortListNullList != null) { + for (java.lang.Short fieldShortListNullItem : fieldShortListNullList) { + if (fieldShortListNullItem == null) { + fieldShortListNullOsList.addNull(); + } else { + fieldShortListNullOsList.addLong(fieldShortListNullItem.longValue()); + } + } + } + + + OsList fieldByteListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldByteListNotNullIndex); + fieldByteListNotNullOsList.removeAll(); + RealmList fieldByteListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldByteListNotNull(); + if (fieldByteListNotNullList != null) { + for (java.lang.Byte fieldByteListNotNullItem : fieldByteListNotNullList) { + if (fieldByteListNotNullItem == null) { + fieldByteListNotNullOsList.addNull(); + } else { + fieldByteListNotNullOsList.addLong(fieldByteListNotNullItem.longValue()); + } + } + } + + + OsList fieldByteListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldByteListNullIndex); + fieldByteListNullOsList.removeAll(); + RealmList fieldByteListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldByteListNull(); + if (fieldByteListNullList != null) { + for (java.lang.Byte fieldByteListNullItem : fieldByteListNullList) { + if (fieldByteListNullItem == null) { + fieldByteListNullOsList.addNull(); + } else { + fieldByteListNullOsList.addLong(fieldByteListNullItem.longValue()); + } + } + } + + + OsList fieldDoubleListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDoubleListNotNullIndex); + fieldDoubleListNotNullOsList.removeAll(); + RealmList fieldDoubleListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDoubleListNotNull(); + if (fieldDoubleListNotNullList != null) { + for (java.lang.Double fieldDoubleListNotNullItem : fieldDoubleListNotNullList) { + if (fieldDoubleListNotNullItem == null) { + fieldDoubleListNotNullOsList.addNull(); + } else { + fieldDoubleListNotNullOsList.addDouble(fieldDoubleListNotNullItem.doubleValue()); + } + } + } + + + OsList fieldDoubleListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDoubleListNullIndex); + fieldDoubleListNullOsList.removeAll(); + RealmList fieldDoubleListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDoubleListNull(); + if (fieldDoubleListNullList != null) { + for (java.lang.Double fieldDoubleListNullItem : fieldDoubleListNullList) { + if (fieldDoubleListNullItem == null) { + fieldDoubleListNullOsList.addNull(); + } else { + fieldDoubleListNullOsList.addDouble(fieldDoubleListNullItem.doubleValue()); + } + } + } + + + OsList fieldFloatListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldFloatListNotNullIndex); + fieldFloatListNotNullOsList.removeAll(); + RealmList fieldFloatListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldFloatListNotNull(); + if (fieldFloatListNotNullList != null) { + for (java.lang.Float fieldFloatListNotNullItem : fieldFloatListNotNullList) { + if (fieldFloatListNotNullItem == null) { + fieldFloatListNotNullOsList.addNull(); + } else { + fieldFloatListNotNullOsList.addFloat(fieldFloatListNotNullItem.floatValue()); + } + } + } + + + OsList fieldFloatListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldFloatListNullIndex); + fieldFloatListNullOsList.removeAll(); + RealmList fieldFloatListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldFloatListNull(); + if (fieldFloatListNullList != null) { + for (java.lang.Float fieldFloatListNullItem : fieldFloatListNullList) { + if (fieldFloatListNullItem == null) { + fieldFloatListNullOsList.addNull(); + } else { + fieldFloatListNullOsList.addFloat(fieldFloatListNullItem.floatValue()); + } + } + } + + + OsList fieldDateListNotNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDateListNotNullIndex); + fieldDateListNotNullOsList.removeAll(); + RealmList fieldDateListNotNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDateListNotNull(); + if (fieldDateListNotNullList != null) { + for (java.util.Date fieldDateListNotNullItem : fieldDateListNotNullList) { + if (fieldDateListNotNullItem == null) { + fieldDateListNotNullOsList.addNull(); + } else { + fieldDateListNotNullOsList.addDate(fieldDateListNotNullItem); + } + } + } + + + OsList fieldDateListNullOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.fieldDateListNullIndex); + fieldDateListNullOsList.removeAll(); + RealmList fieldDateListNullList = ((NullTypesRealmProxyInterface) object).realmGet$fieldDateListNull(); + if (fieldDateListNullList != null) { + for (java.util.Date fieldDateListNullItem : fieldDateListNullList) { + if (fieldDateListNullItem == null) { + fieldDateListNullOsList.addNull(); + } else { + fieldDateListNullOsList.addDate(fieldDateListNullItem); + } + } + } + } } From 535563cf762d09d90fcfede198f86c4b1d56969b Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 7 Sep 2017 16:10:50 +0300 Subject: [PATCH 14/72] minor refactoring --- realm/realm-library/src/main/java/io/realm/RealmList.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index cecb300e4a..3d5aa24cd4 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -121,7 +121,7 @@ public RealmList(E... objects) { RealmList(Class clazz, OsList osList, BaseRealm realm) { this.collection = new io.realm.internal.Collection(realm.sharedRealm, osList, null); this.clazz = clazz; - osListOperator = getOperator(realm, osList, clazz); + osListOperator = getOperator(realm, osList, clazz , null); this.realm = realm; } @@ -129,7 +129,7 @@ public RealmList(E... objects) { this.collection = new io.realm.internal.Collection(realm.sharedRealm, osList, null); this.realm = realm; this.className = className; - osListOperator = getOperator(realm, osList, null); + osListOperator = getOperator(realm, osList, null, className); } OsList getOsList() { @@ -1695,7 +1695,7 @@ private static boolean isClassForRealmModel(Class clazz) { return RealmModel.class.isAssignableFrom(clazz); } - private ManagedListOperator getOperator(BaseRealm realm, OsList osList, @Nullable Class clazz) { + private ManagedListOperator getOperator(BaseRealm realm, OsList osList, @Nullable Class clazz, @Nullable String className) { if (clazz == null || isClassForRealmModel(clazz)) { return new RealmModelListOperator<>(realm, osList, clazz, className); } From 53d88ee899b47895df9cd9eeb9e63eec5ee05fd8 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 7 Sep 2017 16:59:39 +0300 Subject: [PATCH 15/72] implement primitive list supprt for copyFromRealm() --- .../processor/RealmProxyClassGenerator.java | 15 +- .../io/realm/AllTypesRealmProxy.java | 101 +++++++++ .../io/realm/NullTypesRealmProxy.java | 201 ++++++++++++++++++ 3 files changed, 315 insertions(+), 2 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 458b298fae..1b6d562d32 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -1623,8 +1623,18 @@ private void emitCreateDetachedCopyMethod(JavaWriter writer) throws IOException .endControlFlow() .endControlFlow(); } else if (Utils.isRealmValueList(field)) { - // FIXME need to implement logic for value list fields. - + writer + .emitEmptyLine() + .beginControlFlow("do") + .emitStatement("RealmList<%s> managed%sList = realmSource.%s()", + Utils.getGenericTypeQualifiedName(field), fieldName, getter) + .emitStatement("RealmList<%1$s> unmanaged%2$sList = new RealmList<%1$s>()", Utils.getGenericTypeQualifiedName(field), fieldName) + .emitStatement("unmanagedCopy.%s(unmanaged%sList)", setter, fieldName) + .emitStatement("int size = managed%sList.size()", fieldName) + .beginControlFlow("for (int i = 0; i < size; i++)") + .emitStatement("unmanaged%1$sList.add(managed%1$sList.get(i))", fieldName) + .endControlFlow() + .endControlFlow("while (false)"); } else if (Utils.isMutableRealmInteger(field)) { // If the user initializes the unmanaged MutableRealmInteger to null, this will fail mysteriously. writer.emitStatement("unmanagedCopy.%s().set(realmSource.%s().get())", getter, getter); @@ -1633,6 +1643,7 @@ private void emitCreateDetachedCopyMethod(JavaWriter writer) throws IOException } } + writer.emitEmptyLine(); writer.emitStatement("return unmanagedObject"); writer.endMethod(); writer.emitEmptyLine(); diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index b0316135c1..b046361ff1 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -2108,6 +2108,107 @@ public static some.test.AllTypes createDetachedCopy(some.test.AllTypes realmObje unmanagedcolumnRealmListList.add(item); } } + + do { + RealmList managedcolumnStringListList = realmSource.realmGet$columnStringList(); + RealmList unmanagedcolumnStringListList = new RealmList(); + unmanagedCopy.realmSet$columnStringList(unmanagedcolumnStringListList); + int size = managedcolumnStringListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnStringListList.add(managedcolumnStringListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnBinaryListList = realmSource.realmGet$columnBinaryList(); + RealmList unmanagedcolumnBinaryListList = new RealmList(); + unmanagedCopy.realmSet$columnBinaryList(unmanagedcolumnBinaryListList); + int size = managedcolumnBinaryListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnBinaryListList.add(managedcolumnBinaryListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnBooleanListList = realmSource.realmGet$columnBooleanList(); + RealmList unmanagedcolumnBooleanListList = new RealmList(); + unmanagedCopy.realmSet$columnBooleanList(unmanagedcolumnBooleanListList); + int size = managedcolumnBooleanListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnBooleanListList.add(managedcolumnBooleanListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnLongListList = realmSource.realmGet$columnLongList(); + RealmList unmanagedcolumnLongListList = new RealmList(); + unmanagedCopy.realmSet$columnLongList(unmanagedcolumnLongListList); + int size = managedcolumnLongListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnLongListList.add(managedcolumnLongListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnIntegerListList = realmSource.realmGet$columnIntegerList(); + RealmList unmanagedcolumnIntegerListList = new RealmList(); + unmanagedCopy.realmSet$columnIntegerList(unmanagedcolumnIntegerListList); + int size = managedcolumnIntegerListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnIntegerListList.add(managedcolumnIntegerListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnShortListList = realmSource.realmGet$columnShortList(); + RealmList unmanagedcolumnShortListList = new RealmList(); + unmanagedCopy.realmSet$columnShortList(unmanagedcolumnShortListList); + int size = managedcolumnShortListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnShortListList.add(managedcolumnShortListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnByteListList = realmSource.realmGet$columnByteList(); + RealmList unmanagedcolumnByteListList = new RealmList(); + unmanagedCopy.realmSet$columnByteList(unmanagedcolumnByteListList); + int size = managedcolumnByteListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnByteListList.add(managedcolumnByteListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnDoubleListList = realmSource.realmGet$columnDoubleList(); + RealmList unmanagedcolumnDoubleListList = new RealmList(); + unmanagedCopy.realmSet$columnDoubleList(unmanagedcolumnDoubleListList); + int size = managedcolumnDoubleListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnDoubleListList.add(managedcolumnDoubleListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnFloatListList = realmSource.realmGet$columnFloatList(); + RealmList unmanagedcolumnFloatListList = new RealmList(); + unmanagedCopy.realmSet$columnFloatList(unmanagedcolumnFloatListList); + int size = managedcolumnFloatListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnFloatListList.add(managedcolumnFloatListList.get(i)); + } + } while (false); + + do { + RealmList managedcolumnDateListList = realmSource.realmGet$columnDateList(); + RealmList unmanagedcolumnDateListList = new RealmList(); + unmanagedCopy.realmSet$columnDateList(unmanagedcolumnDateListList); + int size = managedcolumnDateListList.size(); + for (int i = 0; i < size; i++) { + unmanagedcolumnDateListList.add(managedcolumnDateListList.get(i)); + } + } while (false); + return unmanagedObject; } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index 266667fd83..2bd7e5c0d2 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -3866,6 +3866,207 @@ public static some.test.NullTypes createDetachedCopy(some.test.NullTypes realmOb // Deep copy of fieldObjectNull unmanagedCopy.realmSet$fieldObjectNull(NullTypesRealmProxy.createDetachedCopy(realmSource.realmGet$fieldObjectNull(), currentDepth + 1, maxDepth, cache)); + + do { + RealmList managedfieldStringListNotNullList = realmSource.realmGet$fieldStringListNotNull(); + RealmList unmanagedfieldStringListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldStringListNotNull(unmanagedfieldStringListNotNullList); + int size = managedfieldStringListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldStringListNotNullList.add(managedfieldStringListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldStringListNullList = realmSource.realmGet$fieldStringListNull(); + RealmList unmanagedfieldStringListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldStringListNull(unmanagedfieldStringListNullList); + int size = managedfieldStringListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldStringListNullList.add(managedfieldStringListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldBinaryListNotNullList = realmSource.realmGet$fieldBinaryListNotNull(); + RealmList unmanagedfieldBinaryListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldBinaryListNotNull(unmanagedfieldBinaryListNotNullList); + int size = managedfieldBinaryListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldBinaryListNotNullList.add(managedfieldBinaryListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldBinaryListNullList = realmSource.realmGet$fieldBinaryListNull(); + RealmList unmanagedfieldBinaryListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldBinaryListNull(unmanagedfieldBinaryListNullList); + int size = managedfieldBinaryListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldBinaryListNullList.add(managedfieldBinaryListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldBooleanListNotNullList = realmSource.realmGet$fieldBooleanListNotNull(); + RealmList unmanagedfieldBooleanListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldBooleanListNotNull(unmanagedfieldBooleanListNotNullList); + int size = managedfieldBooleanListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldBooleanListNotNullList.add(managedfieldBooleanListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldBooleanListNullList = realmSource.realmGet$fieldBooleanListNull(); + RealmList unmanagedfieldBooleanListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldBooleanListNull(unmanagedfieldBooleanListNullList); + int size = managedfieldBooleanListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldBooleanListNullList.add(managedfieldBooleanListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldLongListNotNullList = realmSource.realmGet$fieldLongListNotNull(); + RealmList unmanagedfieldLongListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldLongListNotNull(unmanagedfieldLongListNotNullList); + int size = managedfieldLongListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldLongListNotNullList.add(managedfieldLongListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldLongListNullList = realmSource.realmGet$fieldLongListNull(); + RealmList unmanagedfieldLongListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldLongListNull(unmanagedfieldLongListNullList); + int size = managedfieldLongListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldLongListNullList.add(managedfieldLongListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldIntegerListNotNullList = realmSource.realmGet$fieldIntegerListNotNull(); + RealmList unmanagedfieldIntegerListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldIntegerListNotNull(unmanagedfieldIntegerListNotNullList); + int size = managedfieldIntegerListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldIntegerListNotNullList.add(managedfieldIntegerListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldIntegerListNullList = realmSource.realmGet$fieldIntegerListNull(); + RealmList unmanagedfieldIntegerListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldIntegerListNull(unmanagedfieldIntegerListNullList); + int size = managedfieldIntegerListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldIntegerListNullList.add(managedfieldIntegerListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldShortListNotNullList = realmSource.realmGet$fieldShortListNotNull(); + RealmList unmanagedfieldShortListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldShortListNotNull(unmanagedfieldShortListNotNullList); + int size = managedfieldShortListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldShortListNotNullList.add(managedfieldShortListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldShortListNullList = realmSource.realmGet$fieldShortListNull(); + RealmList unmanagedfieldShortListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldShortListNull(unmanagedfieldShortListNullList); + int size = managedfieldShortListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldShortListNullList.add(managedfieldShortListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldByteListNotNullList = realmSource.realmGet$fieldByteListNotNull(); + RealmList unmanagedfieldByteListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldByteListNotNull(unmanagedfieldByteListNotNullList); + int size = managedfieldByteListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldByteListNotNullList.add(managedfieldByteListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldByteListNullList = realmSource.realmGet$fieldByteListNull(); + RealmList unmanagedfieldByteListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldByteListNull(unmanagedfieldByteListNullList); + int size = managedfieldByteListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldByteListNullList.add(managedfieldByteListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldDoubleListNotNullList = realmSource.realmGet$fieldDoubleListNotNull(); + RealmList unmanagedfieldDoubleListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldDoubleListNotNull(unmanagedfieldDoubleListNotNullList); + int size = managedfieldDoubleListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldDoubleListNotNullList.add(managedfieldDoubleListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldDoubleListNullList = realmSource.realmGet$fieldDoubleListNull(); + RealmList unmanagedfieldDoubleListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldDoubleListNull(unmanagedfieldDoubleListNullList); + int size = managedfieldDoubleListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldDoubleListNullList.add(managedfieldDoubleListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldFloatListNotNullList = realmSource.realmGet$fieldFloatListNotNull(); + RealmList unmanagedfieldFloatListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldFloatListNotNull(unmanagedfieldFloatListNotNullList); + int size = managedfieldFloatListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldFloatListNotNullList.add(managedfieldFloatListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldFloatListNullList = realmSource.realmGet$fieldFloatListNull(); + RealmList unmanagedfieldFloatListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldFloatListNull(unmanagedfieldFloatListNullList); + int size = managedfieldFloatListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldFloatListNullList.add(managedfieldFloatListNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldDateListNotNullList = realmSource.realmGet$fieldDateListNotNull(); + RealmList unmanagedfieldDateListNotNullList = new RealmList(); + unmanagedCopy.realmSet$fieldDateListNotNull(unmanagedfieldDateListNotNullList); + int size = managedfieldDateListNotNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldDateListNotNullList.add(managedfieldDateListNotNullList.get(i)); + } + } while (false); + + do { + RealmList managedfieldDateListNullList = realmSource.realmGet$fieldDateListNull(); + RealmList unmanagedfieldDateListNullList = new RealmList(); + unmanagedCopy.realmSet$fieldDateListNull(unmanagedfieldDateListNullList); + int size = managedfieldDateListNullList.size(); + for (int i = 0; i < size; i++) { + unmanagedfieldDateListNullList.add(managedfieldDateListNullList.get(i)); + } + } while (false); + return unmanagedObject; } From 6738f1d11476bc78a1327b34a39cc9273bef8f83 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Fri, 8 Sep 2017 13:12:50 +0300 Subject: [PATCH 16/72] added a test to get field meta data of primitive lists --- .../java/io/realm/RealmSchemaTests.java | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmSchemaTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmSchemaTests.java index 6db847312d..3bc7d1b6b9 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmSchemaTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmSchemaTests.java @@ -26,14 +26,18 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import io.realm.entities.AllJavaTypes; import io.realm.entities.Cat; import io.realm.entities.Dog; import io.realm.entities.DogPrimaryKey; +import io.realm.entities.NullTypes; import io.realm.entities.Owner; import io.realm.entities.PrimaryKeyAsString; import io.realm.internal.Table; @@ -85,7 +89,7 @@ public RealmSchemaTests(SchemaType type) { public void setUp() { RealmConfiguration realmConfig = configFactory.createConfigurationBuilder() .schema(AllJavaTypes.class, Owner.class, PrimaryKeyAsString.class, Cat.class, Dog.class, - DogPrimaryKey.class) + DogPrimaryKey.class, NullTypes.class) .build(); Realm.getInstance(realmConfig).close(); // create Schema if (type == SchemaType.MUTABLE) { @@ -106,16 +110,18 @@ public void tearDown() { @Test public void getAll() { Set objectSchemas = realmSchema.getAll(); - assertEquals(6, objectSchemas.size()); + assertEquals(7, objectSchemas.size()); - List expectedTables = Arrays.asList( - AllJavaTypes.CLASS_NAME, "Owner", "Cat", "Dog", "DogPrimaryKey", "PrimaryKeyAsString"); + List expectedTables = new ArrayList<>(Arrays.asList( + AllJavaTypes.CLASS_NAME, "Owner", "Cat", "Dog", "DogPrimaryKey", "PrimaryKeyAsString", NullTypes.CLASS_NAME)); for (RealmObjectSchema objectSchema : objectSchemas) { assertThat(objectSchema, CoreMatchers.instanceOf(type.objectSchemaClass)); - if (!expectedTables.contains(objectSchema.getClassName())) { - fail(objectSchema.getClassName() + " was not found"); + if (!expectedTables.remove(objectSchema.getClassName())) { + fail(objectSchema.getClassName() + " is not expected"); } } + assertTrue("expected class is not contained in schema: " + (expectedTables.isEmpty() ? "" : expectedTables.get(0)), + expectedTables.isEmpty()); } @Test @@ -561,4 +567,42 @@ public void rename_shouldUpdateDynamicCache() { assertSame(foo, bar); assertEquals("bar", bar.getClassName()); } + + @Test + public void schemaInformationOfPrimitiveLists() { + Map fieldNameToType = new HashMap<>(); + fieldNameToType.put(NullTypes.FIELD_STRING_LIST_NULL, RealmFieldType.STRING_LIST); + fieldNameToType.put(NullTypes.FIELD_STRING_LIST_NOT_NULL, RealmFieldType.STRING_LIST); + fieldNameToType.put(NullTypes.FIELD_BINARY_LIST_NULL, RealmFieldType.BINARY_LIST); + fieldNameToType.put(NullTypes.FIELD_BINARY_LIST_NOT_NULL, RealmFieldType.BINARY_LIST); + fieldNameToType.put(NullTypes.FIELD_BOOLEAN_LIST_NULL, RealmFieldType.BOOLEAN_LIST); + fieldNameToType.put(NullTypes.FIELD_BOOLEAN_LIST_NOT_NULL, RealmFieldType.BOOLEAN_LIST); + fieldNameToType.put(NullTypes.FIELD_DATE_LIST_NULL, RealmFieldType.DATE_LIST); + fieldNameToType.put(NullTypes.FIELD_DATE_LIST_NOT_NULL, RealmFieldType.DATE_LIST); + fieldNameToType.put(NullTypes.FIELD_DOUBLE_LIST_NULL, RealmFieldType.DOUBLE_LIST); + fieldNameToType.put(NullTypes.FIELD_DOUBLE_LIST_NOT_NULL, RealmFieldType.DOUBLE_LIST); + fieldNameToType.put(NullTypes.FIELD_FLOAT_LIST_NULL, RealmFieldType.FLOAT_LIST); + fieldNameToType.put(NullTypes.FIELD_FLOAT_LIST_NOT_NULL, RealmFieldType.FLOAT_LIST); + fieldNameToType.put(NullTypes.FIELD_LONG_LIST_NULL, RealmFieldType.INTEGER_LIST); + fieldNameToType.put(NullTypes.FIELD_LONG_LIST_NOT_NULL, RealmFieldType.INTEGER_LIST); + fieldNameToType.put(NullTypes.FIELD_INTEGER_LIST_NULL, RealmFieldType.INTEGER_LIST); + fieldNameToType.put(NullTypes.FIELD_INTEGER_LIST_NOT_NULL, RealmFieldType.INTEGER_LIST); + fieldNameToType.put(NullTypes.FIELD_SHORT_LIST_NULL, RealmFieldType.INTEGER_LIST); + fieldNameToType.put(NullTypes.FIELD_SHORT_LIST_NOT_NULL, RealmFieldType.INTEGER_LIST); + fieldNameToType.put(NullTypes.FIELD_BYTE_LIST_NULL, RealmFieldType.INTEGER_LIST); + fieldNameToType.put(NullTypes.FIELD_BYTE_LIST_NOT_NULL, RealmFieldType.INTEGER_LIST); + + final RealmObjectSchema objectSchema = realmSchema.get(NullTypes.CLASS_NAME); + assertNotNull(objectSchema); + + for (Map.Entry entry : fieldNameToType.entrySet()) { + final String fieldName = entry.getKey(); + final RealmFieldType expectedType = entry.getValue(); + + assertEquals(expectedType, objectSchema.getFieldType(fieldName)); + assertEquals(!fieldName.endsWith("_NOT_NULL"), objectSchema.isNullable(fieldName)); + assertEquals(fieldName.endsWith("_NOT_NULL"), objectSchema.isRequired(fieldName)); + assertFalse(objectSchema.isPrimaryKey(fieldName)); + } + } } From 5d3e7b3524d820892995433db174d1cec9bc2b7b Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Fri, 8 Sep 2017 17:33:48 +0300 Subject: [PATCH 17/72] fix test --- .../androidTest/java/io/realm/DynamicRealmObjectTests.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/DynamicRealmObjectTests.java b/realm/realm-library/src/androidTest/java/io/realm/DynamicRealmObjectTests.java index 9877018d9b..c87b63b0ce 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/DynamicRealmObjectTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/DynamicRealmObjectTests.java @@ -1159,7 +1159,11 @@ public void getFieldNames() { String[] expectedKeys = {AllJavaTypes.FIELD_STRING, AllJavaTypes.FIELD_ID, AllJavaTypes.FIELD_LONG, AllJavaTypes.FIELD_SHORT, AllJavaTypes.FIELD_INT, AllJavaTypes.FIELD_BYTE, AllJavaTypes.FIELD_FLOAT, AllJavaTypes.FIELD_DOUBLE, AllJavaTypes.FIELD_BOOLEAN, AllJavaTypes.FIELD_DATE, - AllJavaTypes.FIELD_BINARY, AllJavaTypes.FIELD_OBJECT, AllJavaTypes.FIELD_LIST}; + AllJavaTypes.FIELD_BINARY, AllJavaTypes.FIELD_OBJECT, AllJavaTypes.FIELD_LIST, + AllJavaTypes.FIELD_STRING_LIST, AllJavaTypes.FIELD_BINARY_LIST, AllJavaTypes.FIELD_BOOLEAN_LIST, + AllJavaTypes.FIELD_LONG_LIST, AllJavaTypes.FIELD_INTEGER_LIST, AllJavaTypes.FIELD_SHORT_LIST, + AllJavaTypes.FIELD_BYTE_LIST, AllJavaTypes.FIELD_DOUBLE_LIST, AllJavaTypes.FIELD_FLOAT_LIST, + AllJavaTypes.FIELD_DATE_LIST}; String[] keys = dObjTyped.getFieldNames(); // After the stable ID support, primary key field will be inserted first before others. So even FIELD_STRING is // the first defined field in the class, it will be inserted after FIELD_ID. From 2f5d0f0728fb9c4ce5458c7bc757519ffd7ba858 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sat, 9 Sep 2017 16:06:39 +0300 Subject: [PATCH 18/72] fix #5233 --- .../src/main/cpp/io_realm_internal_OsList.cpp | 11 ++++++++++ realm/realm-library/src/main/cpp/object-store | 2 +- .../src/main/java/io/realm/RealmList.java | 22 +++++++++++++------ .../main/java/io/realm/internal/OsList.java | 6 +++++ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/realm/realm-library/src/main/cpp/io_realm_internal_OsList.cpp b/realm/realm-library/src/main/cpp/io_realm_internal_OsList.cpp index bd0dce8f54..6011634a46 100644 --- a/realm/realm-library/src/main/cpp/io_realm_internal_OsList.cpp +++ b/realm/realm-library/src/main/cpp/io_realm_internal_OsList.cpp @@ -201,6 +201,17 @@ JNIEXPORT jboolean JNICALL Java_io_realm_internal_OsList_nativeIsValid(JNIEnv* e return JNI_FALSE; } +JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeDelete(JNIEnv* env, jclass, jlong list_ptr, jlong index) +{ + TR_ENTER_PTR(list_ptr) + + try { + auto& list = *reinterpret_cast(list_ptr); + list.delete_at(S(index)); + } + CATCH_STD() +} + JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeDeleteAll(JNIEnv* env, jclass, jlong list_ptr) { TR_ENTER_PTR(list_ptr) diff --git a/realm/realm-library/src/main/cpp/object-store b/realm/realm-library/src/main/cpp/object-store index d1a101fda6..4e3e0fbc90 160000 --- a/realm/realm-library/src/main/cpp/object-store +++ b/realm/realm-library/src/main/cpp/object-store @@ -1 +1 @@ -Subproject commit d1a101fda6999e070c1e73cc5aff002c3de7c129 +Subproject commit 4e3e0fbc90b0c5cea53bfe07c2b93da2a033fd5e diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 3d5aa24cd4..21f8a1e920 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -397,7 +397,7 @@ public boolean deleteFirstFromRealm() { public boolean deleteLastFromRealm() { if (isManaged()) { if (!osListOperator.isEmpty()) { - osListOperator.removeLast(); + osListOperator.deleteLast(); modCount++; return true; } else { @@ -546,7 +546,7 @@ public RealmResults sort(String[] fieldNames, Sort[] sortOrders) { public void deleteFromRealm(int location) { if (isManaged()) { checkValidRealm(); - osListOperator.remove(location); + osListOperator.delete(location); modCount++; } else { throw new UnsupportedOperationException(ONLY_IN_MANAGED_MODE_MESSAGE); @@ -655,7 +655,7 @@ public boolean deleteAllFromRealm() { if (isManaged()) { checkValidRealm(); if (!osListOperator.isEmpty()) { - osListOperator.removeAll(); + osListOperator.deleteAll(); modCount++; return true; } else { @@ -1789,13 +1789,21 @@ final void remove(int index) { osList.remove(index); } - final void removeLast() { - osList.remove(osList.size() - 1); - } - final void removeAll() { osList.removeAll(); } + + final void delete(int index) { + osList.delete(index); + } + + final void deleteLast() { + osList.delete(osList.size() - 1); + } + + final void deleteAll() { + osList.deleteAll(); + } } private static final class RealmModelListOperator extends ManagedListOperator { diff --git a/realm/realm-library/src/main/java/io/realm/internal/OsList.java b/realm/realm-library/src/main/java/io/realm/internal/OsList.java index 92bd6fef28..905419216c 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/OsList.java +++ b/realm/realm-library/src/main/java/io/realm/internal/OsList.java @@ -224,6 +224,10 @@ public boolean isValid() { return nativeIsValid(nativePtr); } + public void delete(long index) { + nativeDelete(nativePtr, index); + } + public void deleteAll() { nativeDeleteAll(nativePtr); } @@ -259,6 +263,8 @@ public Table getTargetTable() { private static native boolean nativeIsValid(long nativePtr); + private static native void nativeDelete(long nativePtr, long pos); + private static native void nativeDeleteAll(long nativePtr); private static native void nativeAddNull(long nativePtr); From b6f79306b0b4114821ab88636f2eb96963d58e88 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sat, 9 Sep 2017 16:56:55 +0300 Subject: [PATCH 19/72] move ManagedListOperator classes from the inside of RealmList to outside --- .../src/main/java/io/realm/RealmList.java | 1081 +++++++++-------- 1 file changed, 541 insertions(+), 540 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 21f8a1e920..5bd19df9e4 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -59,9 +59,7 @@ public class RealmList extends AbstractList implements OrderedRealmCollection { private static final String ONLY_IN_MANAGED_MODE_MESSAGE = "This method is only available in managed mode"; - private static final String NULL_OBJECTS_NOT_ALLOWED_MESSAGE = "RealmList does not accept null values"; private static final String ALLOWED_ONLY_FOR_REALM_MODEL_ELEMENT_MESSAGE = "This feature is available only when the element type is implementing RealmModel"; - private static final String INVALID_OBJECT_TYPE_MESSAGE = "Unacceptable value type. Acceptable: %1$s, actual: %2$s"; public static final String REMOVE_OUTSIDE_TRANSACTION_ERROR = "Objects can only be removed from inside a write transaction"; private final io.realm.internal.Collection collection; @@ -1728,690 +1726,693 @@ private ManagedListOperator getOperator(BaseRealm realm, OsList osList, @Null } throw new IllegalArgumentException("Unexpected value class: " + clazz.getName()); } +} - private static abstract class ManagedListOperator { - final BaseRealm realm; - final OsList osList; - @Nullable - final Class clazz; +abstract class ManagedListOperator { + static final String NULL_OBJECTS_NOT_ALLOWED_MESSAGE = "RealmList does not accept null values"; + static final String INVALID_OBJECT_TYPE_MESSAGE = "Unacceptable value type. Acceptable: %1$s, actual: %2$s"; - ManagedListOperator(BaseRealm realm, OsList osList, @Nullable Class clazz) { - this.realm = realm; - this.clazz = clazz; - this.osList = osList; - } + final BaseRealm realm; + final OsList osList; + @Nullable + final Class clazz; - abstract boolean forRealmModel(); + ManagedListOperator(BaseRealm realm, OsList osList, @Nullable Class clazz) { + this.realm = realm; + this.clazz = clazz; + this.osList = osList; + } - OsList getOsList() { - return osList; - } + abstract boolean forRealmModel(); - final boolean isValid() { - return osList.isValid(); - } + OsList getOsList() { + return osList; + } - final int size() { - final long actualSize = osList.size(); - return actualSize < Integer.MAX_VALUE ? (int) actualSize : Integer.MAX_VALUE; - } + final boolean isValid() { + return osList.isValid(); + } - final boolean isEmpty() { - return osList.isEmpty(); - } + final int size() { + final long actualSize = osList.size(); + return actualSize < Integer.MAX_VALUE ? (int) actualSize : Integer.MAX_VALUE; + } - final void checkInsertIndex(int index) { - final int size = size(); - if (index < 0 || size < index) { - throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); - } + final boolean isEmpty() { + return osList.isEmpty(); + } + + final void checkInsertIndex(int index) { + final int size = size(); + if (index < 0 || size < index) { + throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); } + } - final void checkElementExists(int index) { - final int size = size(); - if (index < 0 || size <= index) { - throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); - } + final void checkElementExists(int index) { + final int size = size(); + if (index < 0 || size <= index) { + throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); } + } - @Nullable - abstract T get(int index); - abstract void add(@Nullable Object value); - abstract void insert(int index, @Nullable Object value); - @Nullable - abstract T set(int index, @Nullable Object value); + @Nullable + abstract T get(int index); + abstract void add(@Nullable Object value); + abstract void insert(int index, @Nullable Object value); + @Nullable + abstract T set(int index, @Nullable Object value); - final void move(int oldPos, int newPos) { - osList.move(oldPos, newPos); - } + final void move(int oldPos, int newPos) { + osList.move(oldPos, newPos); + } - final void remove(int index) { - osList.remove(index); - } + final void remove(int index) { + osList.remove(index); + } - final void removeAll() { - osList.removeAll(); - } + final void removeAll() { + osList.removeAll(); + } - final void delete(int index) { - osList.delete(index); - } + final void delete(int index) { + osList.delete(index); + } - final void deleteLast() { - osList.delete(osList.size() - 1); - } + final void deleteLast() { + osList.delete(osList.size() - 1); + } - final void deleteAll() { - osList.deleteAll(); - } + final void deleteAll() { + osList.deleteAll(); } +} - private static final class RealmModelListOperator extends ManagedListOperator { +final class RealmModelListOperator extends ManagedListOperator { - @Nullable - private final String className; + @Nullable + private final String className; - RealmModelListOperator(BaseRealm realm, OsList osList, @Nullable Class clazz, @Nullable String className) { - super(realm, osList, clazz); - this.className = className; - } + RealmModelListOperator(BaseRealm realm, OsList osList, @Nullable Class clazz, @Nullable String className) { + super(realm, osList, clazz); + this.className = className; + } - @Override - boolean forRealmModel() { - return true; - } + @Override + boolean forRealmModel() { + return true; + } - @Override - T get(int index) { - //noinspection unchecked - return (T) realm.get((Class) clazz, className, osList.getUncheckedRow(index)); - } + @Override + T get(int index) { + //noinspection unchecked + return (T) realm.get((Class) clazz, className, osList.getUncheckedRow(index)); + } - @Nonnull - private RealmModel castToNonNullModel(@Nullable Object value) { - if (value == null) { - throw new IllegalArgumentException(NULL_OBJECTS_NOT_ALLOWED_MESSAGE); - } - if (!(value instanceof RealmModel)) { - throw new IllegalArgumentException( - String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, - "java.lang.String", - value.getClass().getName())); - } - return (RealmModel) value; + @Nonnull + private RealmModel castToNonNullModel(@Nullable Object value) { + if (value == null) { + throw new IllegalArgumentException(NULL_OBJECTS_NOT_ALLOWED_MESSAGE); } - - @Override - public void add(@Nullable Object value) { - final RealmModel model = castToNonNullModel(value); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); - osList.addRow(proxy.realmGet$proxyState().getRow$realm().getIndex()); + if (!(value instanceof RealmModel)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.String", + value.getClass().getName())); } + return (RealmModel) value; + } - @Override - public void insert(int index, @Nullable Object value) { - final RealmModel model = castToNonNullModel(value); - checkInsertIndex(index); + @Override + public void add(@Nullable Object value) { + final RealmModel model = castToNonNullModel(value); + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); + osList.addRow(proxy.realmGet$proxyState().getRow$realm().getIndex()); + } - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); - osList.insertRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); - } + @Override + public void insert(int index, @Nullable Object value) { + final RealmModel model = castToNonNullModel(value); + checkInsertIndex(index); - @Override - protected T set(int index, @Nullable Object value) { - final RealmModel model = castToNonNullModel(value); - checkElementExists(index); + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); + osList.insertRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); + } - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); - //noinspection unchecked - final T oldObject = get(index); - osList.setRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); - return oldObject; - } + @Override + protected T set(int index, @Nullable Object value) { + final RealmModel model = castToNonNullModel(value); + checkElementExists(index); + + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); + //noinspection unchecked + final T oldObject = get(index); + osList.setRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); + return oldObject; + } - // Transparently copies an unmanaged object or managed object from another Realm to the Realm backing this RealmList. - private E copyToRealmIfNeeded(E object) { - if (object instanceof RealmObjectProxy) { - RealmObjectProxy proxy = (RealmObjectProxy) object; + // Transparently copies an unmanaged object or managed object from another Realm to the Realm backing this RealmList. + private E copyToRealmIfNeeded(E object) { + if (object instanceof RealmObjectProxy) { + RealmObjectProxy proxy = (RealmObjectProxy) object; - if (proxy instanceof DynamicRealmObject) { - //noinspection ConstantConditions - @Nonnull - String listClassName = className; - if (proxy.realmGet$proxyState().getRealm$realm() == realm) { - String objectClassName = ((DynamicRealmObject) object).getType(); - if (listClassName.equals(objectClassName)) { - // Same Realm instance and same target table - return object; - } else { - // Different target table - throw new IllegalArgumentException(String.format(Locale.US, - "The object has a different type from list's." + - " Type of the list is '%s', type of object is '%s'.", listClassName, objectClassName)); - } - } else if (realm.threadId == proxy.realmGet$proxyState().getRealm$realm().threadId) { - // We don't support moving DynamicRealmObjects across Realms automatically. The overhead is too big as - // you have to run a full schema validation for each object. - // And copying from another Realm instance pointed to the same Realm file is not supported as well. - throw new IllegalArgumentException("Cannot copy DynamicRealmObject between Realm instances."); + if (proxy instanceof DynamicRealmObject) { + //noinspection ConstantConditions + @Nonnull + String listClassName = className; + if (proxy.realmGet$proxyState().getRealm$realm() == realm) { + String objectClassName = ((DynamicRealmObject) object).getType(); + if (listClassName.equals(objectClassName)) { + // Same Realm instance and same target table + return object; } else { - throw new IllegalStateException("Cannot copy an object to a Realm instance created in another thread."); + // Different target table + throw new IllegalArgumentException(String.format(Locale.US, + "The object has a different type from list's." + + " Type of the list is '%s', type of object is '%s'.", listClassName, objectClassName)); } + } else if (realm.threadId == proxy.realmGet$proxyState().getRealm$realm().threadId) { + // We don't support moving DynamicRealmObjects across Realms automatically. The overhead is too big as + // you have to run a full schema validation for each object. + // And copying from another Realm instance pointed to the same Realm file is not supported as well. + throw new IllegalArgumentException("Cannot copy DynamicRealmObject between Realm instances."); } else { - // Object is already in this realm - if (proxy.realmGet$proxyState().getRow$realm() != null && proxy.realmGet$proxyState().getRealm$realm().getPath().equals(realm.getPath())) { - if (realm != proxy.realmGet$proxyState().getRealm$realm()) { - throw new IllegalArgumentException("Cannot copy an object from another Realm instance."); - } - return object; + throw new IllegalStateException("Cannot copy an object to a Realm instance created in another thread."); + } + } else { + // Object is already in this realm + if (proxy.realmGet$proxyState().getRow$realm() != null && proxy.realmGet$proxyState().getRealm$realm().getPath().equals(realm.getPath())) { + if (realm != proxy.realmGet$proxyState().getRealm$realm()) { + throw new IllegalArgumentException("Cannot copy an object from another Realm instance."); } + return object; } } + } - // At this point the object can only be a typed object, so the backing Realm cannot be a DynamicRealm. - Realm realm = (Realm) this.realm; - if (realm.getTable(object.getClass()).hasPrimaryKey()) { - return realm.copyToRealmOrUpdate(object); - } else { - return realm.copyToRealm(object); - } + // At this point the object can only be a typed object, so the backing Realm cannot be a DynamicRealm. + Realm realm = (Realm) this.realm; + if (realm.getTable(object.getClass()).hasPrimaryKey()) { + return realm.copyToRealmOrUpdate(object); + } else { + return realm.copyToRealm(object); } } +} - private static final class StringListOperator extends ManagedListOperator { +final class StringListOperator extends ManagedListOperator { - StringListOperator(BaseRealm realm, OsList osList, Class clazz) { - super(realm, osList, clazz); - } + StringListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } - @Override - boolean forRealmModel() { - return false; - } + @Override + boolean forRealmModel() { + return false; + } - @Nullable - @Override - String get(int index) { - return (String) osList.getValue(index); - } + @Nullable + @Override + String get(int index) { + return (String) osList.getValue(index); + } - private void checkValidValue(@Nullable Object value) { - if (value == null) { - // null is always valid (but schema may reject null on insertion). - return; - } - if (!(value instanceof String)) { - throw new IllegalArgumentException( - String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, - "java.lang.String", - value.getClass().getName())); - } + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof String)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.String", + value.getClass().getName())); } + } - @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addString((String) value); - } + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addString((String) value); } + } - @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - checkInsertIndex(index); + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); - if (value == null) { - osList.insertNull(index); - } else { - osList.insertString(index, (String) value); - } + if (value == null) { + osList.insertNull(index); + } else { + osList.insertString(index, (String) value); } + } - @Override - @Nullable - protected String set(int index, @Nullable Object value) { - checkValidValue(value); - checkElementExists(index); + @Override + @Nullable + protected String set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); - final String oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setString(index, (String) value); - } - return oldValue; + final String oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setString(index, (String) value); } + return oldValue; } +} - private static final class LongListOperator extends ManagedListOperator { +final class LongListOperator extends ManagedListOperator { - LongListOperator(BaseRealm realm, OsList osList, Class clazz) { - super(realm, osList, clazz); - } + LongListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } - @Override - boolean forRealmModel() { - return false; - } + @Override + boolean forRealmModel() { + return false; + } - @Nullable - @Override - T get(int index) { - final Long value = (Long) osList.getValue(index); - if (value == null) { - return null; - } - if (clazz == Long.class) { - //noinspection unchecked - return (T) value; - } - if (clazz == Integer.class) { - //noinspection unchecked,UnnecessaryBoxing,ConstantConditions - return clazz.cast(Integer.valueOf(value.intValue())); - } - if (clazz == Short.class) { - //noinspection unchecked,UnnecessaryBoxing,ConstantConditions - return clazz.cast(Short.valueOf(value.shortValue())); - } - if (clazz == Byte.class) { - //noinspection unchecked,UnnecessaryBoxing,ConstantConditions - return clazz.cast(Byte.valueOf(value.byteValue())); - } - //noinspection ConstantConditions - throw new IllegalStateException("Unexpected element type: " + clazz.getName()); + @Nullable + @Override + T get(int index) { + final Long value = (Long) osList.getValue(index); + if (value == null) { + return null; + } + if (clazz == Long.class) { + //noinspection unchecked + return (T) value; + } + if (clazz == Integer.class) { + //noinspection unchecked,UnnecessaryBoxing,ConstantConditions + return clazz.cast(Integer.valueOf(value.intValue())); + } + if (clazz == Short.class) { + //noinspection unchecked,UnnecessaryBoxing,ConstantConditions + return clazz.cast(Short.valueOf(value.shortValue())); + } + if (clazz == Byte.class) { + //noinspection unchecked,UnnecessaryBoxing,ConstantConditions + return clazz.cast(Byte.valueOf(value.byteValue())); } + //noinspection ConstantConditions + throw new IllegalStateException("Unexpected element type: " + clazz.getName()); + } - private void checkValidValue(@Nullable Object value) { - if (value == null) { - // null is always valid (but schema may reject null on insertion). - return; - } - if (!(value instanceof Number)) { - throw new IllegalArgumentException( - String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, - "java.lang.Long, java.lang.Integer, java.lang.Short, java.lang.Byte", - value.getClass().getName())); - } + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Number)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.Long, java.lang.Integer, java.lang.Short, java.lang.Byte", + value.getClass().getName())); } + } - @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addLong(((Number) value).longValue()); - } + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addLong(((Number) value).longValue()); } + } - @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - checkInsertIndex(index); + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); - if (value == null) { - osList.insertNull(index); - } else { - osList.insertLong(index, ((Number) value).longValue()); - } + if (value == null) { + osList.insertNull(index); + } else { + osList.insertLong(index, ((Number) value).longValue()); } + } - @Nullable - @Override - protected T set(int index, @Nullable Object value) { - checkValidValue(value); - checkElementExists(index); + @Nullable + @Override + protected T set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); - final T oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setLong(index, ((Number) value).longValue()); - } - return oldValue; + final T oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setLong(index, ((Number) value).longValue()); } + return oldValue; } +} - private static final class BooleanListOperator extends ManagedListOperator { +final class BooleanListOperator extends ManagedListOperator { - BooleanListOperator(BaseRealm realm, OsList osList, Class clazz) { - super(realm, osList, clazz); - } + BooleanListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } - @Override - boolean forRealmModel() { - return false; - } + @Override + boolean forRealmModel() { + return false; + } - @Nullable - @Override - Boolean get(int index) { - return (Boolean) osList.getValue(index); - } + @Nullable + @Override + Boolean get(int index) { + return (Boolean) osList.getValue(index); + } - private void checkValidValue(@Nullable Object value) { - if (value == null) { - // null is always valid (but schema may reject null on insertion). - return; - } - if (!(value instanceof Boolean)) { - throw new IllegalArgumentException( - String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, - "java.lang.Boolean", - value.getClass().getName())); - } + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Boolean)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.Boolean", + value.getClass().getName())); } + } - @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addBoolean((Boolean) value); - } + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addBoolean((Boolean) value); } + } - @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - checkInsertIndex(index); + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); - if (value == null) { - osList.insertNull(index); - } else { - osList.insertBoolean(index, (Boolean) value); - } + if (value == null) { + osList.insertNull(index); + } else { + osList.insertBoolean(index, (Boolean) value); } + } - @Nullable - @Override - protected Boolean set(int index, @Nullable Object value) { - checkValidValue(value); - checkElementExists(index); + @Nullable + @Override + protected Boolean set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); - final Boolean oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setBoolean(index, (Boolean) value); - } - return oldValue; + final Boolean oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setBoolean(index, (Boolean) value); } + return oldValue; } +} - private static final class BinaryListOperator extends ManagedListOperator { +final class BinaryListOperator extends ManagedListOperator { - BinaryListOperator(BaseRealm realm, OsList osList, Class clazz) { - super(realm, osList, clazz); - } + BinaryListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } - @Override - boolean forRealmModel() { - return false; - } + @Override + boolean forRealmModel() { + return false; + } - @Nullable - @Override - byte[] get(int index) { - return (byte[]) osList.getValue(index); - } + @Nullable + @Override + byte[] get(int index) { + return (byte[]) osList.getValue(index); + } - private void checkValidValue(@Nullable Object value) { - if (value == null) { - // null is always valid (but schema may reject null on insertion). - return; - } - if (!(value instanceof byte[])) { - throw new IllegalArgumentException( - String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, - "byte[]", - value.getClass().getName())); - } + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; } + if (!(value instanceof byte[])) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "byte[]", + value.getClass().getName())); + } + } - @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addBinary((byte[]) value); - } + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addBinary((byte[]) value); } + } - @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - checkInsertIndex(index); + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); - if (value == null) { - osList.insertNull(index); - } else { - osList.insertBinary(index, (byte[]) value); - } + if (value == null) { + osList.insertNull(index); + } else { + osList.insertBinary(index, (byte[]) value); } + } - @Nullable - @Override - protected byte[] set(int index, @Nullable Object value) { - checkValidValue(value); - checkElementExists(index); + @Nullable + @Override + protected byte[] set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); - final byte[] oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setBinary(index, (byte[]) value); - } - return oldValue; + final byte[] oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setBinary(index, (byte[]) value); } + return oldValue; } +} - private static final class DoubleListOperator extends ManagedListOperator { +final class DoubleListOperator extends ManagedListOperator { - DoubleListOperator(BaseRealm realm, OsList osList, Class clazz) { - super(realm, osList, clazz); - } + DoubleListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } - @Override - boolean forRealmModel() { - return false; - } + @Override + boolean forRealmModel() { + return false; + } - @Nullable - @Override - Double get(int index) { - return (Double) osList.getValue(index); - } + @Nullable + @Override + Double get(int index) { + return (Double) osList.getValue(index); + } - private void checkValidValue(@Nullable Object value) { - if (value == null) { - // null is always valid (but schema may reject null on insertion). - return; - } - if (!(value instanceof Number)) { - throw new IllegalArgumentException( - String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, - "java.lang.Number", - value.getClass().getName())); - } + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Number)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.Number", + value.getClass().getName())); } + } - @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addDouble(((Number) value).doubleValue()); - } + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addDouble(((Number) value).doubleValue()); } + } - @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - checkInsertIndex(index); + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); - if (value == null) { - osList.insertNull(index); - } else { - osList.insertDouble(index, ((Number) value).doubleValue()); - } + if (value == null) { + osList.insertNull(index); + } else { + osList.insertDouble(index, ((Number) value).doubleValue()); } + } - @Nullable - @Override - protected Double set(int index, @Nullable Object value) { - checkValidValue(value); - checkElementExists(index); + @Nullable + @Override + protected Double set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); - final Double oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setDouble(index, ((Number) value).doubleValue()); - } - return oldValue; + final Double oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setDouble(index, ((Number) value).doubleValue()); } + return oldValue; } +} - private static final class FloatListOperator extends ManagedListOperator { +final class FloatListOperator extends ManagedListOperator { - FloatListOperator(BaseRealm realm, OsList osList, Class clazz) { - super(realm, osList, clazz); - } + FloatListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } - @Override - boolean forRealmModel() { - return false; - } + @Override + boolean forRealmModel() { + return false; + } - @Nullable - @Override - Float get(int index) { - return (Float) osList.getValue(index); - } + @Nullable + @Override + Float get(int index) { + return (Float) osList.getValue(index); + } - private void checkValidValue(@Nullable Object value) { - if (value == null) { - // null is always valid (but schema may reject null on insertion). - return; - } - if (!(value instanceof Number)) { - throw new IllegalArgumentException( - String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, - "java.lang.Number", - value.getClass().getName())); - } + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Number)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.lang.Number", + value.getClass().getName())); } + } - @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addFloat(((Number) value).floatValue()); - } + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addFloat(((Number) value).floatValue()); } + } - @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - checkInsertIndex(index); + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); - if (value == null) { - osList.insertNull(index); - } else { - osList.insertFloat(index, ((Number) value).floatValue()); - } + if (value == null) { + osList.insertNull(index); + } else { + osList.insertFloat(index, ((Number) value).floatValue()); } + } - @Nullable - @Override - protected Float set(int index, @Nullable Object value) { - checkValidValue(value); - checkElementExists(index); + @Nullable + @Override + protected Float set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); - final Float oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setFloat(index, ((Number) value).floatValue()); - } - return oldValue; + final Float oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setFloat(index, ((Number) value).floatValue()); } + return oldValue; } +} - private static final class DateListOperator extends ManagedListOperator { +final class DateListOperator extends ManagedListOperator { - DateListOperator(BaseRealm realm, OsList osList, Class clazz) { - super(realm, osList, clazz); - } + DateListOperator(BaseRealm realm, OsList osList, Class clazz) { + super(realm, osList, clazz); + } - @Override - boolean forRealmModel() { - return false; - } + @Override + boolean forRealmModel() { + return false; + } - @Nullable - @Override - Date get(int index) { - return (Date) osList.getValue(index); - } + @Nullable + @Override + Date get(int index) { + return (Date) osList.getValue(index); + } - private void checkValidValue(@Nullable Object value) { - if (value == null) { - // null is always valid (but schema may reject null on insertion). - return; - } - if (!(value instanceof Date)) { - throw new IllegalArgumentException( - String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, - "java.util.Date", - value.getClass().getName())); - } + private void checkValidValue(@Nullable Object value) { + if (value == null) { + // null is always valid (but schema may reject null on insertion). + return; + } + if (!(value instanceof Date)) { + throw new IllegalArgumentException( + String.format(Locale.ENGLISH, INVALID_OBJECT_TYPE_MESSAGE, + "java.util.Date", + value.getClass().getName())); } + } - @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addDate((Date) value); - } + @Override + public void add(@Nullable Object value) { + checkValidValue(value); + if (value == null) { + osList.addNull(); + } else { + osList.addDate((Date) value); } + } - @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - checkInsertIndex(index); + @Override + public void insert(int index, @Nullable Object value) { + checkValidValue(value); + checkInsertIndex(index); - if (value == null) { - osList.insertNull(index); - } else { - osList.insertDate(index, (Date) value); - } + if (value == null) { + osList.insertNull(index); + } else { + osList.insertDate(index, (Date) value); } + } - @Nullable - @Override - protected Date set(int index, @Nullable Object value) { - checkValidValue(value); - checkElementExists(index); + @Nullable + @Override + protected Date set(int index, @Nullable Object value) { + checkValidValue(value); + checkElementExists(index); - final Date oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setDate(index, (Date) value); - } - return oldValue; + final Date oldValue = get(index); + if (value == null) { + osList.setNull(index); + } else { + osList.setDate(index, (Date) value); } + return oldValue; } } From 5955ef46871b4ab938d1839965c17e3c4819cfed Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 11 Sep 2017 09:46:18 +0300 Subject: [PATCH 20/72] Implement special handling for byte[] in RealmList --- .../src/main/java/io/realm/RealmList.java | 95 +++++++++++++++++-- 1 file changed, 86 insertions(+), 9 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 5bd19df9e4..2afd12e92e 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -19,6 +19,7 @@ import java.lang.reflect.Array; import java.util.AbstractList; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.ConcurrentModificationException; @@ -119,7 +120,7 @@ public RealmList(E... objects) { RealmList(Class clazz, OsList osList, BaseRealm realm) { this.collection = new io.realm.internal.Collection(realm.sharedRealm, osList, null); this.clazz = clazz; - osListOperator = getOperator(realm, osList, clazz , null); + osListOperator = getOperator(realm, osList, clazz, null); this.realm = realm; } @@ -343,9 +344,31 @@ public boolean remove(@Nullable Object object) { if (isManaged() && !realm.isInTransaction()) { throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR); } + + if (object != null) { + if (clazz != object.getClass()) { + return false; + } + if (clazz == byte[].class) { + // we need special handling for class since equals against byte[] never matches. + return remove((byte[]) object); + } + } return super.remove(object); } + private boolean remove(@Nonnull byte[] value) { + Iterator it = iterator(); + while (it.hasNext()) { + final E e = it.next(); + if (e instanceof byte[] && Arrays.equals(value, (byte[]) e)) { + it.remove(); + return true; + } + } + return false; + } + /** * Removes all occurrences in this {@code Collection} of each object in the * specified {@code Collection}. After this method returns none of the @@ -367,7 +390,27 @@ public boolean removeAll(Collection collection) { if (isManaged() && !realm.isInTransaction()) { throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR); } - return super.removeAll(collection); + + boolean modified = false; + Iterator it = iterator(); + while (it.hasNext()) { + final Object element = it.next(); + if (element instanceof byte[]) { + // we can't use collection.contains() since equals() of byte[] never be true + for (Object a : collection) { + if (a instanceof byte[] && Arrays.equals((byte[]) element, (byte[]) a)) { + it.remove(); + modified = true; + } + } + } else { + if (collection.contains(element)) { + it.remove(); + modified = true; + } + } + } + return modified; } /** @@ -703,14 +746,45 @@ public boolean contains(@Nullable Object object) { } } - for (E e : this) { - if (e.equals(object)) { - return true; + if (object == null) { + for (E e : this) { + if (e == null) { + return true; + } + } + return false; + } else { + if (object instanceof byte[] && clazz == byte[].class) { + // byte[] requires special handling + final byte[] bytesObject = (byte[]) object; + for (E e : this) { + if (Arrays.equals((byte[]) e, bytesObject)) { + return true; + } + } + return false; + } else { + for (E e : this) { + if (e != null && e.equals(object)) { + return true; + } + } + return false; } } - return false; } else { - return unmanagedList.contains(object); + if (object instanceof byte[]) { + // byte[] requires special handling + final byte[] bytesObject = (byte[]) object; + for (E e : this) { + if (e instanceof byte[] && Arrays.equals((byte[]) e, bytesObject)) { + return true; + } + } + return false; + } else { + return unmanagedList.contains(object); + } } } @@ -821,7 +895,7 @@ public String toString() { } } } else { - for (int i = 0; i < size(); i++) { + for (int i = 0; i < size(); i++) { final E value = get(i); if (value instanceof RealmModel) { sb.append(System.identityHashCode(value)); @@ -1778,8 +1852,11 @@ final void checkElementExists(int index) { @Nullable abstract T get(int index); + abstract void add(@Nullable Object value); + abstract void insert(int index, @Nullable Object value); + @Nullable abstract T set(int index, @Nullable Object value); @@ -2002,7 +2079,7 @@ boolean forRealmModel() { @Nullable @Override T get(int index) { - final Long value = (Long) osList.getValue(index); + final Long value = (Long) osList.getValue(index); if (value == null) { return null; } From a0db05301592723ec2190f221de34a892318e3c2 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 11 Sep 2017 12:08:37 +0300 Subject: [PATCH 21/72] avoid unnecessary looping --- realm/realm-library/src/main/java/io/realm/RealmList.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 2afd12e92e..0c5e58b54d 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -396,11 +396,13 @@ public boolean removeAll(Collection collection) { while (it.hasNext()) { final Object element = it.next(); if (element instanceof byte[]) { + final byte[] bytesElement = (byte[]) element; // we can't use collection.contains() since equals() of byte[] never be true for (Object a : collection) { - if (a instanceof byte[] && Arrays.equals((byte[]) element, (byte[]) a)) { + if (a instanceof byte[] && Arrays.equals(bytesElement, (byte[]) a)) { it.remove(); modified = true; + break; } } } else { From b7ab7d753293a2bcfaa4d5ef1cf6375b8a3c91ba Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 11 Sep 2017 12:34:55 +0300 Subject: [PATCH 22/72] use fqcn when makeing a string of value type. --- realm/realm-library/src/main/java/io/realm/RealmList.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 0c5e58b54d..11017e91da 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -866,7 +866,11 @@ public String toString() { //noinspection ConstantConditions,unchecked sb.append(realm.getSchema().getSchemaForClass((Class) clazz).getClassName()); } else { - sb.append(clazz.getSimpleName()); + if (clazz == byte[].class) { + sb.append(clazz.getSimpleName()); + } else { + sb.append(clazz.getName()); + } } } } else { From e837379a7616a47913b929db2e75e9dfb8b8844a Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 11 Sep 2017 12:47:15 +0300 Subject: [PATCH 23/72] fix RealmList.toString() --- .../src/main/java/io/realm/RealmList.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 11017e91da..56118efe35 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -893,7 +893,12 @@ public String toString() { } } else { for (int i = 0; i < size(); i++) { - sb.append(get(i)); + final E value = get(i); + if (value instanceof byte[]) { + sb.append("byte[").append(((byte[]) value).length).append("]"); + } else { + sb.append(value); + } sb.append(separator); } if (0 < size()) { @@ -906,7 +911,11 @@ public String toString() { if (value instanceof RealmModel) { sb.append(System.identityHashCode(value)); } else { - sb.append(value); + if (value instanceof byte[]) { + sb.append("byte[").append(((byte[]) value).length).append("]"); + } else { + sb.append(value); + } } sb.append(separator); } From c7cf4466b3a6d3bcca73b9205fa393231d51a7c5 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 12 Sep 2017 12:14:16 +0300 Subject: [PATCH 24/72] fix a bug --- .../src/main/java/io/realm/RealmList.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index e3a7c27c61..f8d5a3e9a3 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -1496,7 +1496,7 @@ public long[] toLongArray(@SuppressWarnings("SameParameterValue") long valueForN if (!isManaged()) { throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); } - if (clazz == null || Number.class.isAssignableFrom(clazz)) { + if (clazz == null || !Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toLongArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } final int size = size(); @@ -1543,7 +1543,7 @@ public int[] toIntArray(@SuppressWarnings("SameParameterValue") int valueForNull if (!isManaged()) { throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); } - if (clazz == null || Number.class.isAssignableFrom(clazz)) { + if (clazz == null || !Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toIntArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } final int size = size(); @@ -1590,7 +1590,7 @@ public short[] toShortArray(@SuppressWarnings("SameParameterValue") short valueF if (!isManaged()) { throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); } - if (clazz == null || Number.class.isAssignableFrom(clazz)) { + if (clazz == null || !Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toShortArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } final int size = size(); @@ -1637,7 +1637,7 @@ public byte[] toByteArray(@SuppressWarnings("SameParameterValue") byte valueForN if (!isManaged()) { throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); } - if (clazz == null || Number.class.isAssignableFrom(clazz)) { + if (clazz == null || !Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toByteArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } final int size = size(); @@ -1731,7 +1731,7 @@ public double[] toDoubleArray(@SuppressWarnings("SameParameterValue") double val if (!isManaged()) { throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); } - if (clazz == null || Number.class.isAssignableFrom(clazz)) { + if (clazz == null || !Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toDoubleArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } @@ -1779,7 +1779,7 @@ public float[] toFloatArray(@SuppressWarnings("SameParameterValue") float valueF if (!isManaged()) { throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); } - if (clazz == null || Number.class.isAssignableFrom(clazz)) { + if (clazz == null || !Number.class.isAssignableFrom(clazz)) { throw new IllegalStateException("toFloatArray() is only supported when the element type is implementing 'java.lang.Number' interface."); } From 66557fd4a5fff2bb8a4fc5dc249c92aa276e08a4 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 12 Sep 2017 14:13:31 +0300 Subject: [PATCH 25/72] fix bugs --- .../src/main/java/io/realm/RealmList.java | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index f8d5a3e9a3..579354b6e1 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -1304,7 +1304,6 @@ public T[] toArray(T[] a) { } final Class componentType = a.getClass().getComponentType(); - final OsList osList = osListOperator.getOsList(); final int size = size(); if (componentType == String.class) { if (a.length < size) { @@ -1330,6 +1329,11 @@ public T[] toArray(T[] a) { //noinspection unchecked a[i] = (T) e; } else { + if (!(e instanceof Number)) { + throw new ArrayStoreException(String.format(Locale.ENGLISH, + "The element of type %1$s can't be stored into the array of %2$s", + e.getClass().getName(), a.getClass().getComponentType())); + } //noinspection unchecked a[i] = (T) Long.valueOf(((Number) e).longValue()); } @@ -1348,8 +1352,13 @@ public T[] toArray(T[] a) { if (e == null || e instanceof Integer) { //noinspection unchecked - a[i] = null; + a[i] = (T) e; } else { + if (!(e instanceof Number)) { + throw new ArrayStoreException(String.format(Locale.ENGLISH, + "The element of type %1$s can't be stored into the array of %2$s", + e.getClass().getName(), a.getClass().getComponentType())); + } //noinspection unchecked a[i] = (T) Integer.valueOf(((Number) e).intValue()); } @@ -1367,8 +1376,13 @@ public T[] toArray(T[] a) { final E e = osListOperator.get(i); if (e == null || e instanceof Short) { //noinspection unchecked - a[i] = null; + a[i] = (T) e; } else { + if (!(e instanceof Number)) { + throw new ArrayStoreException(String.format(Locale.ENGLISH, + "The element of type %1$s can't be stored into the array of %2$s", + e.getClass().getName(), a.getClass().getComponentType())); + } //noinspection unchecked a[i] = (T) Short.valueOf(((Number) e).shortValue()); } @@ -1386,8 +1400,13 @@ public T[] toArray(T[] a) { final E e = osListOperator.get(i); if (e == null || e instanceof Byte) { //noinspection unchecked - a[i] = null; + a[i] = (T) e; } else { + if (!(e instanceof Number)) { + throw new ArrayStoreException(String.format(Locale.ENGLISH, + "The element of type %1$s can't be stored into the array of %2$s", + e.getClass().getName(), a.getClass().getComponentType())); + } //noinspection unchecked a[i] = (T) Byte.valueOf(((Number) e).byteValue()); } @@ -1405,8 +1424,13 @@ public T[] toArray(T[] a) { final E e = osListOperator.get(i); if (e == null || e instanceof Double) { //noinspection unchecked - a[i] = null; + a[i] = (T) e; } else { + if (!(e instanceof Number)) { + throw new ArrayStoreException(String.format(Locale.ENGLISH, + "The element of type %1$s can't be stored into the array of %2$s", + e.getClass().getName(), a.getClass().getComponentType())); + } //noinspection unchecked a[i] = (T) Double.valueOf(((Number) e).doubleValue()); } @@ -1424,8 +1448,13 @@ public T[] toArray(T[] a) { final E e = osListOperator.get(i); if (e == null || e instanceof Float) { //noinspection unchecked - a[i] = null; + a[i] = (T) e; } else { + if (!(e instanceof Number)) { + throw new ArrayStoreException(String.format(Locale.ENGLISH, + "The element of type %1$s can't be stored into the array of %2$s", + e.getClass().getName(), a.getClass().getComponentType())); + } //noinspection unchecked a[i] = (T) Float.valueOf(((Number) e).floatValue()); } From b4ff2e077b38bc041b1254e4f518018cec91ef5d Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 12 Sep 2017 14:14:35 +0300 Subject: [PATCH 26/72] add instrumentation tests --- .../realm/ManagedRealmListForValueTests.java | 1451 +++++++++++++++++ ...ManagedRealmListForValue_toArrayTests.java | 838 ++++++++++ 2 files changed, 2289 insertions(+) create mode 100644 realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java create mode 100644 realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java new file mode 100644 index 0000000000..0025990be9 --- /dev/null +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -0,0 +1,1451 @@ +/* + * Copyright 2017 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.annotation.Nullable; + +import io.realm.entities.NullTypes; +import io.realm.rule.RunInLooperThread; +import io.realm.rule.RunTestInLooperThread; +import io.realm.rule.TestRealmConfigurationFactory; + +import static io.realm.ManagedRealmListForValueTests.ListType.BINARY_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.BOOLEAN_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.BYTE_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.DATE_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.DOUBLE_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.FLOAT_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.INTEGER_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.LONG_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.SHORT_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.STRING_LIST; +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + + +/** + * Unit tests specific for RealmList with value elements. + */ +@RunWith(Parameterized.class) +public class ManagedRealmListForValueTests extends CollectionTests { + + static final int NON_NULL_TEST_SIZE = 10; + static final int NULLABLE_TEST_SIZE = NON_NULL_TEST_SIZE * 2; + + enum ListType { + STRING_LIST(RealmFieldType.STRING_LIST, String.class.getName()), + BOOLEAN_LIST(RealmFieldType.BOOLEAN_LIST, Boolean.class.getName()), + BINARY_LIST(RealmFieldType.BINARY_LIST, byte[].class.getSimpleName()/* using simple name since array class is a bit special */), + LONG_LIST(RealmFieldType.INTEGER_LIST, Long.class.getName()), + INTEGER_LIST(RealmFieldType.INTEGER_LIST, Integer.class.getName()), + SHORT_LIST(RealmFieldType.INTEGER_LIST, Short.class.getName()), + BYTE_LIST(RealmFieldType.INTEGER_LIST, Byte.class.getName()), + DOUBLE_LIST(RealmFieldType.DOUBLE_LIST, Double.class.getName()), + FLOAT_LIST(RealmFieldType.FLOAT_LIST, Float.class.getName()), + DATE_LIST(RealmFieldType.DATE_LIST, Date.class.getName()); + + private final RealmFieldType fieldType; + private final String valueTypeName; + + ListType(RealmFieldType fieldType, String valueTypeName) { + this.fieldType = fieldType; + this.valueTypeName = valueTypeName; + } + + @SuppressWarnings("unused") + public RealmFieldType getFieldType() { + return fieldType; + } + + public String getValueTypeName() { + return valueTypeName; + } + } + + @Parameterized.Parameters(name = "{index}: Type: {0}, Nullable?: {1}") + public static Collection parameters() { + final List paramsList = new ArrayList<>(); + for (ListType listType : ListType.values()) { + paramsList.add(new Object[] {listType, Boolean.TRUE}); + paramsList.add(new Object[] {listType, Boolean.FALSE}); + } + return paramsList; + } + + @Rule + public final TestRealmConfigurationFactory configFactory = new TestRealmConfigurationFactory(); + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Rule + public final RunInLooperThread looperThread = new RunInLooperThread(); + + @Parameterized.Parameter + public ListType listType; + + @Parameterized.Parameter(1) + public Boolean typeIsNullable; + + private Realm realm; + private NullTypes object; + private RealmList list; + + @SuppressWarnings("unchecked") + @Before + public void setUp() throws Exception { + final RealmConfiguration.Builder configurationBuilder = configFactory.createConfigurationBuilder(); + configurationBuilder.schema(NullTypes.class); + RealmConfiguration realmConfig = configurationBuilder.build(); + + realm = Realm.getInstance(realmConfig); + + realm.beginTransaction(); + object = realm.createObject(NullTypes.class, 0); + for (ListType type : ListType.values()) { + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + switch (type) { + case STRING_LIST: { + final RealmList nonnull = object.getFieldStringListNotNull(); + nonnull.add(generateValue(STRING_LIST, i)); + final RealmList nullable = object.getFieldStringListNull(); + nullable.add("" + i); + nullable.add(null); + } + break; + case BOOLEAN_LIST: { + final RealmList nonnull = object.getFieldBooleanListNotNull(); + nonnull.add(generateValue(BOOLEAN_LIST, i)); + final RealmList nullable = object.getFieldBooleanListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case BINARY_LIST: { + final RealmList nonnull = object.getFieldBinaryListNotNull(); + nonnull.add(generateValue(BINARY_LIST, i)); + final RealmList nullable = object.getFieldBinaryListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case LONG_LIST: { + final RealmList nonnull = object.getFieldLongListNotNull(); + nonnull.add(generateValue(LONG_LIST, i)); + final RealmList nullable = object.getFieldLongListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case INTEGER_LIST: { + final RealmList nonnull = object.getFieldIntegerListNotNull(); + nonnull.add(generateValue(INTEGER_LIST, i)); + final RealmList nullable = object.getFieldIntegerListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case SHORT_LIST: { + final RealmList nonnull = object.getFieldShortListNotNull(); + nonnull.add(generateValue(SHORT_LIST, i)); + final RealmList nullable = object.getFieldShortListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case BYTE_LIST: { + final RealmList nonnull = object.getFieldByteListNotNull(); + nonnull.add(generateValue(BYTE_LIST, i)); + final RealmList nullable = object.getFieldByteListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case DOUBLE_LIST: { + final RealmList nonnull = object.getFieldDoubleListNotNull(); + nonnull.add(generateValue(DOUBLE_LIST, i)); + final RealmList nullable = object.getFieldDoubleListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case FLOAT_LIST: { + final RealmList nonnull = object.getFieldFloatListNotNull(); + nonnull.add(generateValue(FLOAT_LIST, i)); + final RealmList nullable = object.getFieldFloatListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case DATE_LIST: { + final RealmList nonnull = object.getFieldDateListNotNull(); + nonnull.add(generateValue(DATE_LIST, i)); + final RealmList nullable = object.getFieldDateListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + default: + throw new AssertionError("unexpected value type: " + listType.name()); + } + } + } + realm.commitTransaction(); + + list = getListFor(object, listType, typeIsNullable); + } + + static RealmList getListFor(NullTypes object, ListType listType, boolean nullable) { + switch (listType) { + case STRING_LIST: + return nullable ? object.getFieldStringListNull() : object.getFieldStringListNotNull(); + case BOOLEAN_LIST: + return nullable ? object.getFieldBooleanListNull() : object.getFieldBooleanListNotNull(); + case BINARY_LIST: + return nullable ? object.getFieldBinaryListNull() : object.getFieldBinaryListNotNull(); + case LONG_LIST: + return nullable ? object.getFieldLongListNull() : object.getFieldLongListNotNull(); + case INTEGER_LIST: + return nullable ? object.getFieldIntegerListNull() : object.getFieldIntegerListNotNull(); + case SHORT_LIST: + return nullable ? object.getFieldShortListNull() : object.getFieldShortListNotNull(); + case BYTE_LIST: + return nullable ? object.getFieldByteListNull() : object.getFieldByteListNotNull(); + case DOUBLE_LIST: + return nullable ? object.getFieldDoubleListNull() : object.getFieldDoubleListNotNull(); + case FLOAT_LIST: + return nullable ? object.getFieldFloatListNull() : object.getFieldFloatListNotNull(); + case DATE_LIST: + return nullable ? object.getFieldDateListNull() : object.getFieldDateListNotNull(); + default: + throw new AssertionError("unexpected value type: " + listType.name()); + } + } + + @After + public void tearDown() throws Exception { + if (realm != null) { + realm.close(); + } + } + + static Object generateValue(ListType listType, int i) { + switch (listType) { + case STRING_LIST: + return "" + i; + case BOOLEAN_LIST: + return i % 2 == 0 ? Boolean.FALSE : Boolean.TRUE; + case BINARY_LIST: + return new byte[] {(byte) i}; + case LONG_LIST: + return (long) i; + case INTEGER_LIST: + return i; + case SHORT_LIST: + return (short) i; + case BYTE_LIST: + return (byte) i; + case DOUBLE_LIST: + return (double) i; + case FLOAT_LIST: + return (float) i; + case DATE_LIST: + return new Date(i); + default: + throw new AssertionError("unexpected value type: " + listType.name()); + } + } + + private static Object generateHugeValue(ListType listType, int size) { + final byte[] bytes = new byte[size]; + switch (listType) { + case STRING_LIST: + Arrays.fill(bytes, (byte) 'a'); + return new String(bytes, Charset.forName("US-ASCII")); + case BINARY_LIST: + return bytes; + default: + throw new AssertionError("'generateHugeValue' does not support this type: " + listType.name()); + } + } + + private void assertValueEquals(@Nullable Object expected, @Nullable Object actual) { + assertValueEquals(null, expected, actual); + } + + private void assertValueEquals(@SuppressWarnings("SameParameterValue") @Nullable String message, @Nullable Object expected, @Nullable Object actual) { + if (listType == BINARY_LIST) { + assertTrue(message, Arrays.equals((byte[]) expected, (byte[]) actual)); + } else { + assertEquals(message, expected, actual); + } + } + + @Test + public void readValues() { + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + switch (listType) { + case STRING_LIST: { + assertEquals(generateValue(STRING_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + case BOOLEAN_LIST: { + assertEquals(generateValue(BOOLEAN_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + case BINARY_LIST: { + assertTrue(Arrays.equals((byte[]) generateValue(BINARY_LIST, i), (byte[]) list.get(typeIsNullable ? (i * 2) : i))); + } + break; + case LONG_LIST: { + //noinspection UnnecessaryBoxing + assertEquals(generateValue(LONG_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + case INTEGER_LIST: { + //noinspection UnnecessaryBoxing + assertEquals(generateValue(INTEGER_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + case SHORT_LIST: { + //noinspection UnnecessaryBoxing + assertEquals(generateValue(SHORT_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + case BYTE_LIST: { + //noinspection UnnecessaryBoxing + assertEquals(generateValue(BYTE_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + case DOUBLE_LIST: { + //noinspection UnnecessaryBoxing + assertEquals(generateValue(DOUBLE_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + case FLOAT_LIST: { + //noinspection UnnecessaryBoxing + assertEquals(generateValue(FLOAT_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + case DATE_LIST: { + assertEquals(generateValue(DATE_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + } + break; + default: + throw new AssertionError("unexpected value type: " + listType.name()); + } + if (typeIsNullable) { + assertNull(list.get(i * 2 + 1)); + } + } + } + + @Test + public void isValid() { + assertTrue(list.isValid()); + + realm.close(); + + assertFalse(list.isValid()); + } + + @Test + public void isValid_whenParentRemoved() { + realm.beginTransaction(); + object.deleteFromRealm(); + realm.commitTransaction(); + + // RealmList contained in removed object is invalid. + assertFalse(list.isValid()); + } + + private static final int HEADER_SIZE = 8; + private static final int MAX_STRING_SIZE = 0xFFFFF8 - HEADER_SIZE - 1; + private static final int MAX_BINARY_SIZE = 0xFFFFF8 - HEADER_SIZE; + + @Test + public void add_exceedingSizeLimitValueThrows() { + if (listType != STRING_LIST && listType != BINARY_LIST) { + return; + } + + final int sizeLimit; + switch (listType) { + case STRING_LIST: + sizeLimit = MAX_STRING_SIZE; + break; + case BINARY_LIST: + sizeLimit = MAX_BINARY_SIZE; + break; + default: + throw new AssertionError("Unexpected list type: " + listType.name()); + } + + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + //noinspection unchecked + list.add(generateHugeValue(listType, sizeLimit)); + } + }); + + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + thrown.expect(IllegalArgumentException.class); + //noinspection unchecked + list.add(generateHugeValue(listType, sizeLimit + 1)); + } + }); + } + + @Test + public void move_outOfBoundsLowerThrows() { + realm.beginTransaction(); + try { + list.move(0, -1); + fail("Indexes < 0 should throw an exception"); + } catch (IndexOutOfBoundsException ignored) { + } finally { + realm.cancelTransaction(); + } + } + + @Test + public void move_outOfBoundsHigherThrows() { + realm.beginTransaction(); + try { + list.move(list.size() - 1, list.size()); + fail("Indexes >= size() should throw an exception"); + } catch (IndexOutOfBoundsException ignored) { + ignored.printStackTrace(); + } finally { + realm.cancelTransaction(); + } + } + + @Test + public void clear_then_add() { + realm.beginTransaction(); + list.clear(); + + assertTrue(list.isEmpty()); + + //noinspection unchecked + list.add(generateValue(listType, -100)); + + realm.commitTransaction(); + + assertEquals(1, list.size()); + } + + @Test + public void size() { + assertEquals(typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE, list.size()); + } + + @Test + public void remove_nonNullByIndex() { + final int targetIndex = 6; + + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + final Object removed = list.remove(targetIndex); + final int dataIndex = typeIsNullable ? targetIndex / 2 : targetIndex; + assertValueEquals(generateValue(listType, dataIndex), removed); + } + }); + + assertEquals(typeIsNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); + for (int i = 0; i < list.size(); i++) { + final int originalIndex = i < targetIndex ? i : i + 1; + if (typeIsNullable) { + if (originalIndex % 2 == 1) { + assertNull(list.get(i)); + } else { + assertValueEquals(generateValue(listType, originalIndex / 2), list.get(i)); + } + } else { + assertValueEquals(generateValue(listType, originalIndex), list.get(i)); + } + } + } + + @Test + public void remove_nullByIndex() { + if (!typeIsNullable) { + return; + } + + final int targetIndex = 7; + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + assertNull(list.remove(targetIndex)); + assertEquals(NULLABLE_TEST_SIZE - 1, list.size()); + } + }); + + for (int i = 0; i < list.size(); i++) { + final int originalIndex = i < targetIndex ? i : i + 1; + if (originalIndex % 2 == 1) { + assertNull(list.get(i)); + } else { + assertValueEquals(generateValue(listType, originalIndex / 2), list.get(i)); + } + } + } + + @Test + public void remove_first() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + final Object removed = list.remove(0); + assertValueEquals(generateValue(listType, 0), removed); + } + }); + + assertEquals((typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1, list.size()); + } + + @Test + public void remove_last() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + final Object removed = list.remove((typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1); + if (typeIsNullable) { + assertNull(removed); + } else { + assertValueEquals(generateValue(listType, NON_NULL_TEST_SIZE - 1), removed); + } + } + }); + + assertEquals((typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1, list.size()); + } + + @Test + public void remove_fromEmptyListThrows() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + list.clear(); + thrown.expect(IndexOutOfBoundsException.class); + list.remove(0); + } + }); + } + + @Test + public void remove_byObject() { + final Object value = list.get(0); + final int initialSize = list.size(); + + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + assertTrue(list.remove(value)); + } + }); + + assertEquals(initialSize - 1, list.size()); + } + + @Test + public void remove_byNull() { + final int initialSize = list.size(); + + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + if (typeIsNullable) { + assertTrue(list.remove(null)); + } else { + assertFalse(list.remove(null)); + } + } + }); + + assertEquals(typeIsNullable ? (initialSize - 1) : initialSize, list.size()); + } + + @Test + public void deleteFirst() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + assertTrue(list.deleteFirstFromRealm()); + } + }); + + assertEquals(typeIsNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); + for (int i = 0; i < list.size(); i++) { + final int originalIndex = i + 1; + if (typeIsNullable) { + if (originalIndex % 2 == 1) { + assertNull(list.get(i)); + } else { + assertValueEquals(generateValue(listType, originalIndex / 2), list.get(i)); + } + } else { + assertValueEquals(generateValue(listType, originalIndex), list.get(i)); + } + } + } + + @Test + public void deleteLast() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + assertTrue(list.deleteLastFromRealm()); + } + }); + + assertEquals(typeIsNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); + for (int i = 0; i < list.size(); i++) { + if (typeIsNullable) { + if (i % 2 == 1) { + assertNull(list.get(i)); + } else { + assertValueEquals(generateValue(listType, i / 2), list.get(i)); + } + } else { + assertValueEquals(generateValue(listType, i), list.get(i)); + } + } + } + + @Test + public void add_atAfterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + //noinspection unchecked + list.add(generateValue(listType, 100)); + } + + @Test + public void set_afterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + //noinspection unchecked + list.set(0, generateValue(listType, 100)); + } + + @Test + public void move_afterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + list.move(0, 1); + } + + @Test + public void clear_afterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + list.clear(); + } + + @Test + public void remove_atAfterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + list.remove(0); + } + + @Test + public void remove_objectAfterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + list.remove(generateValue(listType, 4)); + } + + @Test + public void remove_unsupportedTypeIgnored() { + final int initialSize = list.size(); + + final List unsupportedValues = Arrays.asList( + new int[] {0}, + new StringBuilder("0") + ); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + for (Object unsupportedValue : unsupportedValues) { + //noinspection UseBulkOperation + list.remove(unsupportedValue); + } + } + }); + + assertEquals(initialSize, list.size()); + } + + @Test + public void removeAll() { + final List toBeRemoved = Arrays.asList( + null, + generateValue(listType, 2), + generateValue(listType, 4)); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + //noinspection unchecked + list.removeAll(toBeRemoved); + } + }); + + if (listType == BOOLEAN_LIST) { + assertEquals(NON_NULL_TEST_SIZE / 2, list.size()); + } else { + assertEquals(NON_NULL_TEST_SIZE - 2, list.size()); + } + } + + @Test + public void removeAll_unsupportedTypeIgnored() { + final int initialSize = list.size(); + + final List unsupportedValues = Arrays.asList( + new int[] {0}, + new StringBuilder("0") + ); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + //noinspection unchecked + list.removeAll(unsupportedValues); + } + }); + + assertEquals(initialSize, list.size()); + } + + @Test + public void removeAll_afterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + //noinspection unchecked + list.removeAll(Collections.emptyList()); + } + + @Test + public void get_afterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + list.get(0); + } + + @Test + public void first_afterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + list.first(); + } + + @Test + public void last_afterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + list.last(); + } + + @Test + public void size_afterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + + thrown.expect(IllegalStateException.class); + list.size(); + } + + @Test(expected = IllegalStateException.class) + public void where() { + list.where(); + } + + @Test + public void toString_() { + final StringBuilder sb = new StringBuilder("RealmList<").append(listType.getValueTypeName()).append(">@["); + final String separator = ","; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + final Object value = generateValue(listType, i); + + if (value instanceof byte[]) { + sb.append("byte[").append(((byte[]) value).length).append("]"); + } else { + sb.append(value); + } + sb.append(separator); + if (typeIsNullable) { + sb.append("null").append(separator); + } + } + sb.setLength(sb.length() - separator.length()); + sb.append("]"); + + assertEquals(sb.toString(), list.toString()); + } + + @Test + public void toString_AfterContainerObjectRemoved() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object.deleteFromRealm(); + } + }); + assertEquals("RealmList<" + listType.getValueTypeName() + ">@[invalid]", list.toString()); + } + + @Test + public void deleteAllFromRealm() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + list.deleteAllFromRealm(); + } + }); + + assertEquals(0, list.size()); + } + + @Test + public void deleteAllFromRealm_outsideTransaction() { + try { + list.deleteAllFromRealm(); + fail("deleteAllFromRealm should be called in a transaction."); + } catch (IllegalStateException e) { + assertThat(e.getMessage(), containsString("Must be in a write transaction ")); + } + } + + @Test + public void deleteAllFromRealm_emptyList() { + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + list.deleteAllFromRealm(); + } + }); + assertEquals(0, list.size()); + + // The dogs is empty now. + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + list.deleteAllFromRealm(); + } + }); + assertEquals(0, list.size()); + } + + @Test + public void deleteAllFromRealm_invalidListShouldThrow() { + realm.close(); + realm = null; + + try { + list.deleteAllFromRealm(); + fail("dogs is invalid and it should throw an exception"); + } catch (IllegalStateException e) { + assertEquals("This Realm instance has already been closed, making it unusable.", e.getMessage()); + } + } + + @Test + @Ignore + @RunTestInLooperThread + public void changeListener_forAddObject() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + + // add 3 elements as an initial data + //noinspection unchecked + list.add(generateValue(listType, 0)); + //noinspection unchecked + list.add(generateValue(listType, 100)); + //noinspection unchecked + list.add(generateValue(listType, 200)); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(1, changes.getInsertions().length); + assertEquals(0, changes.getDeletions().length); + assertEquals(0, changes.getChanges().length); + assertEquals(3, changes.getInsertions()[0]); + assertEquals(1, listenerCalledCount.getAndIncrement()); + } + }); + + realm.beginTransaction(); + //noinspection unchecked + list.add(generateValue(listType, 100)); + realm.commitTransaction(); + + assertEquals(2, listenerCalledCount.get()); + looperThread.testComplete(); + } + + @Test + @Ignore("unexpected fail. Unexpected insertion index.") + @RunTestInLooperThread + public void changeListener_forAddAt() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + + // add 3 elements as an initial data + //noinspection unchecked + list.add(generateValue(listType, 0)); + //noinspection unchecked + list.add(generateValue(listType, 100)); + //noinspection unchecked + list.add(generateValue(listType, 200)); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(1, changes.getInsertions().length); + assertEquals(0, changes.getDeletions().length); + assertEquals(0, changes.getChanges().length); + assertEquals(1, changes.getInsertions()[0]); + assertEquals(1, listenerCalledCount.getAndIncrement()); + } + }); + + realm.beginTransaction(); + //noinspection unchecked + list.add(1, generateValue(listType, 500)); + realm.commitTransaction(); + + assertEquals(2, listenerCalledCount.get()); + looperThread.testComplete(); + } + + @Test + @Ignore("unexpected fail. Listener never be called.") + @RunTestInLooperThread + public void changeListener_forSet() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + + // add 3 elements as an initial data + //noinspection unchecked + list.add(generateValue(listType, 0)); + //noinspection unchecked + list.add(generateValue(listType, 100)); + //noinspection unchecked + list.add(generateValue(listType, 200)); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(0, changes.getInsertions().length); + assertEquals(0, changes.getDeletions().length); + assertEquals(1, changes.getChanges().length); + assertEquals(1, changes.getChanges()[0]); + assertEquals(1, listenerCalledCount.getAndIncrement()); + } + }); + + realm.beginTransaction(); + //noinspection unchecked + list.set(1, generateValue(listType, 500)); + realm.commitTransaction(); + + assertEquals(2, listenerCalledCount.get()); + looperThread.testComplete(); + } + + @Test + @Ignore("unexpected fail. Unexpected deletion index.") + @RunTestInLooperThread + public void changeListener_forRemoveAt() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + + // add 3 elements as an initial data + //noinspection unchecked + list.add(generateValue(listType, 0)); + //noinspection unchecked + list.add(generateValue(listType, 100)); + //noinspection unchecked + list.add(generateValue(listType, 200)); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(0, changes.getInsertions().length); + assertEquals(1, changes.getDeletions().length); + assertEquals(0, changes.getChanges().length); + assertEquals(1, changes.getDeletions()[0]); + assertEquals(1, listenerCalledCount.getAndIncrement()); + } + }); + + realm.beginTransaction(); + //noinspection unchecked + list.remove(1); + realm.commitTransaction(); + + assertEquals(2, listenerCalledCount.get()); + looperThread.testComplete(); + } + + @Test + @Ignore("unexpected fail. Unexpected deletion index.") + @RunTestInLooperThread + public void changeListener_forRemoveObject() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + + // add 3 elements as an initial data + //noinspection unchecked + list.add(generateValue(listType, 0)); + //noinspection unchecked + list.add(generateValue(listType, 100)); + //noinspection unchecked + list.add(generateValue(listType, 200)); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { assertEquals(1, changes.getInsertions().length); + assertEquals(0, changes.getInsertions().length); + assertEquals(1, changes.getDeletions().length); + assertEquals(0, changes.getChanges().length); + assertEquals(1, changes.getDeletions()[0]); + assertEquals(1, listenerCalledCount.getAndIncrement()); + } + }); + + realm.beginTransaction(); + //noinspection unchecked + list.remove(generateValue(listType, 100)); + realm.commitTransaction(); + + assertEquals(2, listenerCalledCount.get()); + looperThread.testComplete(); + } + + @Test + @Ignore("unexpected native crash") + @RunTestInLooperThread + public void changeListener_forRemoveAll() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + + // add 3 elements as an initial data + //noinspection unchecked + list.add(generateValue(listType, 0)); + //noinspection unchecked + list.add(generateValue(listType, 100)); + //noinspection unchecked + list.add(generateValue(listType, 200)); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(0, changes.getInsertions().length); + assertEquals(listType == BOOLEAN_LIST ? 3 : 2, changes.getDeletions().length); + assertEquals(0, changes.getChanges().length); + assertEquals(1, changes.getDeletionRanges().length); + assertEquals(listType == BOOLEAN_LIST ? 0 : 1, changes.getDeletionRanges()[0].startIndex); + assertEquals(listType == BOOLEAN_LIST ? 3 : 2, changes.getDeletionRanges()[0].length); + assertEquals(1, listenerCalledCount.getAndIncrement()); + } + }); + + realm.beginTransaction(); + //noinspection unchecked + list.removeAll(Arrays.asList(generateValue(listType, 100), generateValue(listType, 200), generateValue(listType, 300))); + realm.commitTransaction(); + + assertEquals(2, listenerCalledCount.get()); + looperThread.testComplete(); + } + + @Test + @Ignore("unexpected fail. Unexpected deletion index.") + @RunTestInLooperThread + public void changeListener_forDeleteAt() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + + // add 3 elements as an initial data + //noinspection unchecked + list.add(generateValue(listType, 0)); + //noinspection unchecked + list.add(generateValue(listType, 100)); + //noinspection unchecked + list.add(generateValue(listType, 200)); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(0, changes.getInsertions().length); + assertEquals(1, changes.getDeletions().length); + assertEquals(0, changes.getChanges().length); + assertEquals(1, changes.getDeletions()[0]); + assertEquals(1, listenerCalledCount.getAndIncrement()); + } + }); + + realm.beginTransaction(); + //noinspection unchecked + list.deleteFromRealm(1); + realm.commitTransaction(); + + assertEquals(2, listenerCalledCount.get()); + looperThread.testComplete(); + } + + @Test + @Ignore("unexpected native crash") + @RunTestInLooperThread + public void changeListener_forDeleteAll() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + + // add 3 elements as an initial data + //noinspection unchecked + list.add(generateValue(listType, 0)); + //noinspection unchecked + list.add(generateValue(listType, 100)); + //noinspection unchecked + list.add(generateValue(listType, 200)); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(0, changes.getInsertions().length); + assertEquals(3, changes.getDeletions().length); + assertEquals(0, changes.getChanges().length); + assertEquals(1, changes.getDeletionRanges().length); + assertEquals(0, changes.getDeletionRanges()[0].startIndex); + assertEquals(3, changes.getDeletionRanges()[0].length); + assertEquals(1, listenerCalledCount.getAndIncrement()); + } + }); + + realm.beginTransaction(); + //noinspection unchecked + list.deleteAllFromRealm(); + realm.commitTransaction(); + + assertEquals(2, listenerCalledCount.get()); + looperThread.testComplete(); + } + + @Test + @RunTestInLooperThread + public void removeAllChangeListeners() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + } + }); + + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + fail(); + } + }); + //noinspection unchecked + list.addChangeListener(new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + fail(); + } + }); + + list.removeAllChangeListeners(); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + // This one is added after removal, so it should be triggered. + //noinspection unchecked + list.addChangeListener(new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + listenerCalledCount.incrementAndGet(); + looperThread.testComplete(); + } + }); + + // This should trigger the listener if there is any. + realm.beginTransaction(); + //noinspection unchecked + list.add(generateValue(listType, 500)); + realm.commitTransaction(); + + assertEquals(1, listenerCalledCount.get()); + } + + @SuppressWarnings("unchecked") + @Test + @RunTestInLooperThread + public void removeChangeListener() { + Realm realm = looperThread.getRealm(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + object = realm.createObject(NullTypes.class, 1000); + list = getListFor(object, listType, typeIsNullable); + } + }); + + final AtomicInteger listenerCalledCount = new AtomicInteger(0); + RealmChangeListener> listener1 = new RealmChangeListener>() { + @Override + public void onChange(RealmList element) { + fail(); + } + }; + OrderedRealmCollectionChangeListener> listener2 = + new OrderedRealmCollectionChangeListener>() { + @Override + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(0, listenerCalledCount.getAndIncrement()); + looperThread.testComplete(); + } + }; + + list.addChangeListener(listener1); + list.addChangeListener(listener2); + + list.removeChangeListener(listener1); + + // This should trigger the listener if there is any. + realm.beginTransaction(); + list.add(generateValue(listType, 500)); + realm.commitTransaction(); + assertEquals(1, listenerCalledCount.get()); + } +} diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java new file mode 100644 index 0000000000..dd383a4242 --- /dev/null +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java @@ -0,0 +1,838 @@ +/* + * Copyright 2017 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import io.realm.ManagedRealmListForValueTests.ListType; +import io.realm.entities.NullTypes; +import io.realm.rule.RunInLooperThread; +import io.realm.rule.TestRealmConfigurationFactory; + +import static io.realm.ManagedRealmListForValueTests.ListType.BINARY_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.BOOLEAN_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.BYTE_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.DATE_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.DOUBLE_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.FLOAT_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.INTEGER_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.LONG_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.SHORT_LIST; +import static io.realm.ManagedRealmListForValueTests.ListType.STRING_LIST; +import static io.realm.ManagedRealmListForValueTests.NON_NULL_TEST_SIZE; +import static io.realm.ManagedRealmListForValueTests.NULLABLE_TEST_SIZE; +import static io.realm.ManagedRealmListForValueTests.generateValue; +import static io.realm.ManagedRealmListForValueTests.getListFor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + + +/** + * Unit tests specific for RealmList with value elements. + */ +@RunWith(Parameterized.class) +public class ManagedRealmListForValue_toArrayTests extends CollectionTests { + + @Parameterized.Parameters(name = "{index}: Type: {0}, Nullable?: {1}") + public static Collection parameters() { + final List paramsList = new ArrayList<>(); + for (ListType listType : ListType.values()) { + paramsList.add(new Object[] {listType, Boolean.TRUE}); + paramsList.add(new Object[] {listType, Boolean.FALSE}); + } + return paramsList; + } + + @Rule + public final TestRealmConfigurationFactory configFactory = new TestRealmConfigurationFactory(); + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Rule + public final RunInLooperThread looperThread = new RunInLooperThread(); + + @Parameterized.Parameter + public ListType listType; + + @Parameterized.Parameter(1) + public Boolean typeIsNullable; + + private Realm realm; + private RealmList list; + + @SuppressWarnings("unchecked") + @Before + public void setUp() throws Exception { + final RealmConfiguration.Builder configurationBuilder = configFactory.createConfigurationBuilder(); + configurationBuilder.schema(NullTypes.class); + RealmConfiguration realmConfig = configurationBuilder.build(); + + realm = Realm.getInstance(realmConfig); + + realm.beginTransaction(); + final NullTypes object = realm.createObject(NullTypes.class, 0); + for (ListType type : ListType.values()) { + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + switch (type) { + case STRING_LIST: { + final RealmList nonnull = object.getFieldStringListNotNull(); + nonnull.add(generateValue(STRING_LIST, i)); + final RealmList nullable = object.getFieldStringListNull(); + nullable.add("" + i); + nullable.add(null); + } + break; + case BOOLEAN_LIST: { + final RealmList nonnull = object.getFieldBooleanListNotNull(); + nonnull.add(generateValue(BOOLEAN_LIST, i)); + final RealmList nullable = object.getFieldBooleanListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case BINARY_LIST: { + final RealmList nonnull = object.getFieldBinaryListNotNull(); + nonnull.add(generateValue(BINARY_LIST, i)); + final RealmList nullable = object.getFieldBinaryListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case LONG_LIST: { + final RealmList nonnull = object.getFieldLongListNotNull(); + nonnull.add(generateValue(LONG_LIST, i)); + final RealmList nullable = object.getFieldLongListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case INTEGER_LIST: { + final RealmList nonnull = object.getFieldIntegerListNotNull(); + nonnull.add(generateValue(INTEGER_LIST, i)); + final RealmList nullable = object.getFieldIntegerListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case SHORT_LIST: { + final RealmList nonnull = object.getFieldShortListNotNull(); + nonnull.add(generateValue(SHORT_LIST, i)); + final RealmList nullable = object.getFieldShortListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case BYTE_LIST: { + final RealmList nonnull = object.getFieldByteListNotNull(); + nonnull.add(generateValue(BYTE_LIST, i)); + final RealmList nullable = object.getFieldByteListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case DOUBLE_LIST: { + final RealmList nonnull = object.getFieldDoubleListNotNull(); + nonnull.add(generateValue(DOUBLE_LIST, i)); + final RealmList nullable = object.getFieldDoubleListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case FLOAT_LIST: { + final RealmList nonnull = object.getFieldFloatListNotNull(); + nonnull.add(generateValue(FLOAT_LIST, i)); + final RealmList nullable = object.getFieldFloatListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + case DATE_LIST: { + final RealmList nonnull = object.getFieldDateListNotNull(); + nonnull.add(generateValue(DATE_LIST, i)); + final RealmList nullable = object.getFieldDateListNull(); + nullable.add(nonnull.last()); + nullable.add(null); + } + break; + default: + throw new AssertionError("unexpected value type: " + listType.name()); + } + } + } + realm.commitTransaction(); + + list = getListFor(object, listType, typeIsNullable); + } + + @After + public void tearDown() throws Exception { + if (realm != null) { + realm.close(); + } + } + + private static final Set NON_NUMBER_LIST_TYPES; + + static { + final HashSet set = new HashSet<>(); + set.add(STRING_LIST); + set.add(BOOLEAN_LIST); + set.add(BINARY_LIST); + set.add(DATE_LIST); + + NON_NUMBER_LIST_TYPES = Collections.unmodifiableSet(set); + } + + @Test + public void toLongArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toLongArray(); + // should not reach here + return; + } + + final long[] expected = new long[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (long) generateValue(LONG_LIST, i); + expected[i * 2 + 1] = 0L; + } else { + expected[i] = (long) generateValue(LONG_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toLongArray())); + } + + @Test + public void toLongArrayWithNullValue() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + final long valueForNull = Long.MIN_VALUE; + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toLongArray(valueForNull); + // should not reach here + return; + } + + final long[] expected = new long[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (long) generateValue(LONG_LIST, i); + expected[i * 2 + 1] = valueForNull; + } else { + expected[i] = (long) generateValue(LONG_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toLongArray(valueForNull))); + } + + @Test + public void toIntArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toIntArray(); + // should not reach here + return; + } + + final int[] expected = new int[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (int) generateValue(INTEGER_LIST, i); + expected[i * 2 + 1] = 0; + } else { + expected[i] = (int) generateValue(INTEGER_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toIntArray())); + } + + @Test + public void toIntArrayWithNullValue() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + final int valueForNull = Integer.MIN_VALUE; + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toIntArray(valueForNull); + // should not reach here + return; + } + + final int[] expected = new int[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (int) generateValue(INTEGER_LIST, i); + expected[i * 2 + 1] = valueForNull; + } else { + expected[i] = (int) generateValue(INTEGER_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toIntArray(valueForNull))); + } + + @Test + public void toShortArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toShortArray(); + // should not reach here + return; + } + + final short[] expected = new short[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (short) generateValue(SHORT_LIST, i); + expected[i * 2 + 1] = 0; + } else { + expected[i] = (short) generateValue(SHORT_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toShortArray())); + } + + @Test + public void toShortArrayWithNullValue() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + final short valueForNull = Short.MIN_VALUE; + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toShortArray(valueForNull); + // should not reach here + return; + } + + final short[] expected = new short[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (short) generateValue(SHORT_LIST, i); + expected[i * 2 + 1] = valueForNull; + } else { + expected[i] = (short) generateValue(SHORT_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toShortArray(valueForNull))); + } + + @Test + public void toByteArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toByteArray(); + // should not reach here + return; + } + + final byte[] expected = new byte[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (byte) generateValue(BYTE_LIST, i); + expected[i * 2 + 1] = 0; + } else { + expected[i] = (byte) generateValue(BYTE_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toByteArray())); + } + + @Test + public void toByteArrayWithNullValue() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + final byte valueForNull = Byte.MIN_VALUE; + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toByteArray(valueForNull); + // should not reach here + return; + } + + final byte[] expected = new byte[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (byte) generateValue(BYTE_LIST, i); + expected[i * 2 + 1] = valueForNull; + } else { + expected[i] = (byte) generateValue(BYTE_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toByteArray(valueForNull))); + } + + @Test + public void toDoubleArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toDoubleArray(); + // should not reach here + return; + } + + final double[] expected = new double[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (double) generateValue(DOUBLE_LIST, i); + expected[i * 2 + 1] = 0D; + } else { + expected[i] = (double) generateValue(DOUBLE_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toDoubleArray())); + } + + @Test + public void toDoubleArrayWithNullValue() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + final double valueForNull = Double.NEGATIVE_INFINITY; + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toDoubleArray(valueForNull); + // should not reach here + return; + } + + final double[] expected = new double[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (double) generateValue(DOUBLE_LIST, i); + expected[i * 2 + 1] = valueForNull; + } else { + expected[i] = (double) generateValue(DOUBLE_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toDoubleArray(valueForNull))); + } + + @Test + public void toFloatArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toFloatArray(); + // should not reach here + return; + } + + final float[] expected = new float[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (float) generateValue(FLOAT_LIST, i); + expected[i * 2 + 1] = 0L; + } else { + expected[i] = (float) generateValue(FLOAT_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toFloatArray())); + } + + @Test + public void toFloatArrayWithNullValue() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + final float valueForNull = Float.NEGATIVE_INFINITY; + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toFloatArray(valueForNull); + // should not reach here + return; + } + + final float[] expected = new float[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (float) generateValue(FLOAT_LIST, i); + expected[i * 2 + 1] = valueForNull; + } else { + expected[i] = (float) generateValue(FLOAT_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toFloatArray(valueForNull))); + } + + @Test + public void toBooleanArray() { + final boolean exceptionExpected = (listType != BOOLEAN_LIST); + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toBooleanArray(); + // should not reach here + return; + } + + final boolean[] expected = new boolean[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (boolean) generateValue(BOOLEAN_LIST, i); + expected[i * 2 + 1] = false; + } else { + expected[i] = (boolean) generateValue(BOOLEAN_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toBooleanArray())); + } + + @Test + public void toBooleanArrayWithNullValue() { + final boolean exceptionExpected = (listType != BOOLEAN_LIST); + + final boolean valueForNull = true; + + if (exceptionExpected) { + thrown.expect(IllegalStateException.class); + list.toBooleanArray(valueForNull); + // should not reach here + return; + } + + final boolean[] expected = new boolean[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (boolean) generateValue(BOOLEAN_LIST, i); + expected[i * 2 + 1] = valueForNull; + } else { + expected[i] = (boolean) generateValue(BOOLEAN_LIST, i); + } + } + assertTrue(Arrays.equals(expected, list.toBooleanArray(valueForNull))); + } + + @Test + public void toArray() { + final Object[] expected = new Object[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = generateValue(listType, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = generateValue(listType, i); + } + } + + if (listType != BINARY_LIST) { + assertTrue(Arrays.equals(expected, list.toArray())); + } else { + final Object[] array = list.toArray(); + assertEquals(expected.length, array.length); + for (int i = 0; i < expected.length; i++) { + if (expected[i] == null) { + assertNull(array[i]); + } else { + assertTrue(array[i] instanceof byte[]); + assertTrue(Arrays.equals((byte[]) expected[i], (byte[]) array[i])); + } + } + } + } + + @Test + public void toArray_withStringArray() { + final boolean exceptionExpected = (listType != STRING_LIST); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new String[0]); + // should not reach here + return; + } + + final String[] expected = new String[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (String) generateValue(STRING_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (String) generateValue(STRING_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new String[0]); + assertEquals(String.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } + + @Test + public void toArray_withBooleanArray() { + final boolean exceptionExpected = (listType != BOOLEAN_LIST); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new Boolean[0]); + // should not reach here + return; + } + + final Boolean[] expected = new Boolean[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (Boolean) generateValue(BOOLEAN_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (Boolean) generateValue(BOOLEAN_LIST, i); + } + } + + final Object[] returnedArray = list.toArray(new Boolean[0]); + assertEquals(Boolean.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } + + @Test + public void toArray_withBinaryArray() { + final boolean exceptionExpected = (listType != BINARY_LIST); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new byte[0][]); + // should not reach here + return; + } + + final byte[][] expected = new byte[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE][]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (byte[]) generateValue(BINARY_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (byte[]) generateValue(BINARY_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new byte[0][]); + assertEquals(byte[].class, returnedArray.getClass().getComponentType()); + + assertEquals(expected.length, returnedArray.length); + for (int i = 0; i < expected.length; i++) { + if (expected[i] == null) { + assertNull(returnedArray[i]); + } else { + assertTrue(returnedArray[i] instanceof byte[]); + assertTrue(Arrays.equals(expected[i], (byte[]) returnedArray[i])); + } + } + } + + @Test + public void toArray_withLongArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new Long[0]); + // should not reach here + return; + } + + final Long[] expected = new Long[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (Long) generateValue(LONG_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (Long) generateValue(LONG_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new Long[0]); + assertEquals(Long.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } + + @Test + public void toArray_withIntegerArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new Integer[0]); + // should not reach here + return; + } + + final Integer[] expected = new Integer[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (Integer) generateValue(INTEGER_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (Integer) generateValue(INTEGER_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new Integer[0]); + assertEquals(Integer.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } + + @Test + public void toArray_withShortArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new Short[0]); + // should not reach here + return; + } + + final Short[] expected = new Short[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (Short) generateValue(SHORT_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (Short) generateValue(SHORT_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new Short[0]); + assertEquals(Short.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } + + @Test + public void toArray_withByteArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new Byte[0]); + // should not reach here + return; + } + + final Byte[] expected = new Byte[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (Byte) generateValue(BYTE_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (Byte) generateValue(BYTE_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new Byte[0]); + assertEquals(Byte.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } + + @Test + public void toArray_withDoubleArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new Double[0]); + // should not reach here + return; + } + + final Double[] expected = new Double[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (Double) generateValue(DOUBLE_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (Double) generateValue(DOUBLE_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new Double[0]); + assertEquals(Double.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } + + @Test + public void toArray_withFloatArray() { + final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new Float[0]); + // should not reach here + return; + } + + final Float[] expected = new Float[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (Float) generateValue(FLOAT_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (Float) generateValue(FLOAT_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new Float[0]); + assertEquals(Float.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } + + @Test + public void toArray_withDateArray() { + final boolean exceptionExpected = (listType != DATE_LIST); + + if (exceptionExpected) { + thrown.expect(ArrayStoreException.class); + list.toArray(new Date[0]); + // should not reach here + return; + } + + final Date[] expected = new Date[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; + for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { + if (typeIsNullable) { + expected[i * 2] = (Date) generateValue(DATE_LIST, i); + expected[i * 2 + 1] = null; + } else { + expected[i] = (Date) generateValue(DATE_LIST, i); + } + } + final Object[] returnedArray = list.toArray(new Date[0]); + assertEquals(Date.class, returnedArray.getClass().getComponentType()); + assertTrue(Arrays.equals(expected, returnedArray)); + } +} \ No newline at end of file From 0ad34c46bf662723071abe796cd758492fb5c756 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 12 Sep 2017 18:00:23 +0300 Subject: [PATCH 27/72] fix a bug that annotation processor always generates schema of primitive list as nullable --- .../processor/RealmProxyClassGenerator.java | 8 ++-- .../io/realm/AllTypesRealmProxy.java | 24 +++++------ .../io/realm/NullTypesRealmProxy.java | 42 +++++++++---------- .../io/realm/LinkingObjectsManagedTests.java | 4 +- .../java/io/realm/internal/OsListTests.java | 14 +++---- .../io/realm/internal/OsObjectSchemaInfo.java | 4 +- .../main/java/io/realm/internal/Property.java | 4 +- 7 files changed, 50 insertions(+), 50 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index d267840dd0..6e14d242f6 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -726,14 +726,14 @@ private void emitCreateExpectedObjectSchemaInfo(JavaWriter writer) throws IOExce case OBJECT: String fieldTypeSimpleName = Utils.getFieldTypeSimpleName(field); - writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.OBJECT, \"%s\")", + writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.OBJECT, \"%s\", !Property.REQUIRED)", fieldName, fieldTypeSimpleName); break; case LIST: // only for model list. String genericTypeSimpleName = Utils.getGenericTypeSimpleName(field); - writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.LIST, \"%s\")", + writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.LIST, \"%s\", !Property.REQUIRED)", fieldName, genericTypeSimpleName); break; @@ -744,8 +744,8 @@ private void emitCreateExpectedObjectSchemaInfo(JavaWriter writer) throws IOExce case DATE_LIST: case FLOAT_LIST: case DOUBLE_LIST: - writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", %s, \"%s\")", - fieldName, fieldType.getRealmType(), ""); + writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", %s, \"%s\", %s)", + fieldName, fieldType.getRealmType(), "", metadata.isElementNullable(field) ? "!Property.REQUIRED" : "Property.REQUIRED"); break; case BACKLINK: diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index b046361ff1..89bc5d08ee 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -869,18 +869,18 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { builder.addPersistedProperty("columnDate", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED); builder.addPersistedProperty("columnBinary", RealmFieldType.BINARY, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED); builder.addPersistedProperty("columnMutableRealmInteger", RealmFieldType.INTEGER, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); - builder.addPersistedLinkProperty("columnObject", RealmFieldType.OBJECT, "AllTypes"); - builder.addPersistedLinkProperty("columnRealmList", RealmFieldType.LIST, "AllTypes"); - builder.addPersistedLinkProperty("columnStringList", RealmFieldType.STRING_LIST, ""); - builder.addPersistedLinkProperty("columnBinaryList", RealmFieldType.BINARY_LIST, ""); - builder.addPersistedLinkProperty("columnBooleanList", RealmFieldType.BOOLEAN_LIST, ""); - builder.addPersistedLinkProperty("columnLongList", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("columnIntegerList", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("columnShortList", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("columnByteList", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("columnDoubleList", RealmFieldType.DOUBLE_LIST, ""); - builder.addPersistedLinkProperty("columnFloatList", RealmFieldType.FLOAT_LIST, ""); - builder.addPersistedLinkProperty("columnDateList", RealmFieldType.DATE_LIST, ""); + builder.addPersistedLinkProperty("columnObject", RealmFieldType.OBJECT, "AllTypes", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnRealmList", RealmFieldType.LIST, "AllTypes", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnStringList", RealmFieldType.STRING_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnBinaryList", RealmFieldType.BINARY_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnBooleanList", RealmFieldType.BOOLEAN_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnLongList", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnIntegerList", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnShortList", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnByteList", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnDoubleList", RealmFieldType.DOUBLE_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnFloatList", RealmFieldType.FLOAT_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnDateList", RealmFieldType.DATE_LIST, "", !Property.REQUIRED); builder.addComputedLinkProperty("parentObjects", "AllTypes", "columnObject"); return builder.build(); } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index 2bd7e5c0d2..451180b310 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -1728,27 +1728,27 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { builder.addPersistedProperty("fieldDoubleNull", RealmFieldType.DOUBLE, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); builder.addPersistedProperty("fieldDateNotNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED); builder.addPersistedProperty("fieldDateNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldObjectNull", RealmFieldType.OBJECT, "NullTypes"); - builder.addPersistedLinkProperty("fieldStringListNotNull", RealmFieldType.STRING_LIST, ""); - builder.addPersistedLinkProperty("fieldStringListNull", RealmFieldType.STRING_LIST, ""); - builder.addPersistedLinkProperty("fieldBinaryListNotNull", RealmFieldType.BINARY_LIST, ""); - builder.addPersistedLinkProperty("fieldBinaryListNull", RealmFieldType.BINARY_LIST, ""); - builder.addPersistedLinkProperty("fieldBooleanListNotNull", RealmFieldType.BOOLEAN_LIST, ""); - builder.addPersistedLinkProperty("fieldBooleanListNull", RealmFieldType.BOOLEAN_LIST, ""); - builder.addPersistedLinkProperty("fieldLongListNotNull", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("fieldLongListNull", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("fieldIntegerListNotNull", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("fieldIntegerListNull", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("fieldShortListNotNull", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("fieldShortListNull", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("fieldByteListNotNull", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("fieldByteListNull", RealmFieldType.INTEGER_LIST, ""); - builder.addPersistedLinkProperty("fieldDoubleListNotNull", RealmFieldType.DOUBLE_LIST, ""); - builder.addPersistedLinkProperty("fieldDoubleListNull", RealmFieldType.DOUBLE_LIST, ""); - builder.addPersistedLinkProperty("fieldFloatListNotNull", RealmFieldType.FLOAT_LIST, ""); - builder.addPersistedLinkProperty("fieldFloatListNull", RealmFieldType.FLOAT_LIST, ""); - builder.addPersistedLinkProperty("fieldDateListNotNull", RealmFieldType.DATE_LIST, ""); - builder.addPersistedLinkProperty("fieldDateListNull", RealmFieldType.DATE_LIST, ""); + builder.addPersistedLinkProperty("fieldObjectNull", RealmFieldType.OBJECT, "NullTypes", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldStringListNotNull", RealmFieldType.STRING_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldStringListNull", RealmFieldType.STRING_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldBinaryListNotNull", RealmFieldType.BINARY_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldBinaryListNull", RealmFieldType.BINARY_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldBooleanListNotNull", RealmFieldType.BOOLEAN_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldBooleanListNull", RealmFieldType.BOOLEAN_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldLongListNotNull", RealmFieldType.INTEGER_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldLongListNull", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldIntegerListNotNull", RealmFieldType.INTEGER_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldIntegerListNull", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldShortListNotNull", RealmFieldType.INTEGER_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldShortListNull", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldByteListNotNull", RealmFieldType.INTEGER_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldByteListNull", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldDoubleListNotNull", RealmFieldType.DOUBLE_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldDoubleListNull", RealmFieldType.DOUBLE_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldFloatListNotNull", RealmFieldType.FLOAT_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldFloatListNull", RealmFieldType.FLOAT_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldDateListNotNull", RealmFieldType.DATE_LIST, "", Property.REQUIRED); + builder.addPersistedLinkProperty("fieldDateListNull", RealmFieldType.DATE_LIST, "", !Property.REQUIRED); return builder.build(); } diff --git a/realm/realm-library/src/androidTest/java/io/realm/LinkingObjectsManagedTests.java b/realm/realm-library/src/androidTest/java/io/realm/LinkingObjectsManagedTests.java index 0561dd58ed..9bbe61a441 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/LinkingObjectsManagedTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/LinkingObjectsManagedTests.java @@ -599,7 +599,7 @@ public void migration_backlinkedSourceFieldDoesntExist() throws ClassNotFoundExc .build(); OsObjectSchemaInfo sourceSchemaInfo = new OsObjectSchemaInfo.Builder("BacklinksSource") .addPersistedProperty("name", RealmFieldType.STRING, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED) - .addPersistedLinkProperty("child", RealmFieldType.OBJECT, "BacklinksTarget") + .addPersistedLinkProperty("child", RealmFieldType.OBJECT, "BacklinksTarget", !Property.REQUIRED) .build(); Map, OsObjectSchemaInfo> infoMap = new HashMap, OsObjectSchemaInfo>(); @@ -643,7 +643,7 @@ public void migration_backlinkedSourceFieldWrongType() { OsObjectSchemaInfo sourceSchemaInfo = new OsObjectSchemaInfo.Builder("BacklinksSource") .addPersistedProperty("name", RealmFieldType.STRING, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED) .addPersistedLinkProperty("child", RealmFieldType.OBJECT, - "BacklinksSource"/*"BacklinksTarget" is the original value*/) + "BacklinksSource"/*"BacklinksTarget" is the original value*/, !Property.REQUIRED) .build(); Map, OsObjectSchemaInfo> infoMap = new HashMap, OsObjectSchemaInfo>(); diff --git a/realm/realm-library/src/androidTest/java/io/realm/internal/OsListTests.java b/realm/realm-library/src/androidTest/java/io/realm/internal/OsListTests.java index a5e40c7048..f8de6f463a 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/internal/OsListTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/internal/OsListTests.java @@ -51,13 +51,13 @@ public class OsListTests { @Before public void setUp() { OsObjectSchemaInfo objectSchemaInfo = new OsObjectSchemaInfo.Builder("TestModel") - .addPersistedLinkProperty("longList", RealmFieldType.INTEGER_LIST, null) - .addPersistedLinkProperty("doubleList", RealmFieldType.DOUBLE_LIST, null) - .addPersistedLinkProperty("floatList", RealmFieldType.FLOAT_LIST, null) - .addPersistedLinkProperty("booleanList", RealmFieldType.BOOLEAN_LIST, null) - .addPersistedLinkProperty("binaryList", RealmFieldType.BINARY_LIST, null) - .addPersistedLinkProperty("dateList", RealmFieldType.DATE_LIST, null) - .addPersistedLinkProperty("stringList", RealmFieldType.STRING_LIST, null) + .addPersistedLinkProperty("longList", RealmFieldType.INTEGER_LIST, null, !Property.REQUIRED) + .addPersistedLinkProperty("doubleList", RealmFieldType.DOUBLE_LIST, null, !Property.REQUIRED) + .addPersistedLinkProperty("floatList", RealmFieldType.FLOAT_LIST, null, !Property.REQUIRED) + .addPersistedLinkProperty("booleanList", RealmFieldType.BOOLEAN_LIST, null, !Property.REQUIRED) + .addPersistedLinkProperty("binaryList", RealmFieldType.BINARY_LIST, null, !Property.REQUIRED) + .addPersistedLinkProperty("dateList", RealmFieldType.DATE_LIST, null, !Property.REQUIRED) + .addPersistedLinkProperty("stringList", RealmFieldType.STRING_LIST, null, !Property.REQUIRED) .build(); List objectSchemaInfoList = new ArrayList(); objectSchemaInfoList.add(objectSchemaInfo); diff --git a/realm/realm-library/src/main/java/io/realm/internal/OsObjectSchemaInfo.java b/realm/realm-library/src/main/java/io/realm/internal/OsObjectSchemaInfo.java index 2a18201359..3361bea14a 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/OsObjectSchemaInfo.java +++ b/realm/realm-library/src/main/java/io/realm/internal/OsObjectSchemaInfo.java @@ -71,8 +71,8 @@ public Builder addPersistedProperty(String name, RealmFieldType type, boolean is * {@link RealmFieldType#LIST}. * @return this {@code OsObjectSchemaInfo.Builder}. */ - public Builder addPersistedLinkProperty(String name, RealmFieldType type, @Nullable String linkedClassName) { - final Property property = new Property(name, type, linkedClassName); + public Builder addPersistedLinkProperty(String name, RealmFieldType type, @Nullable String linkedClassName, boolean required) { + final Property property = new Property(name, type, linkedClassName, required); persistedPropertyList.add(property); return this; } diff --git a/realm/realm-library/src/main/java/io/realm/internal/Property.java b/realm/realm-library/src/main/java/io/realm/internal/Property.java index c79c7ca259..1ba2f95399 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/Property.java +++ b/realm/realm-library/src/main/java/io/realm/internal/Property.java @@ -73,9 +73,9 @@ public class Property implements NativeObject { this(nativeCreatePersistedProperty(name, convertFromRealmFieldType(type, isRequired), isPrimary, isIndexed)); } - Property(String name, RealmFieldType type, @Nullable String linkedClassName) { + Property(String name, RealmFieldType type, @Nullable String linkedClassName, boolean required) { // Ignore the isRequired when creating the linking property. - this(nativeCreatePersistedLinkProperty(name, convertFromRealmFieldType(type, false), linkedClassName)); + this(nativeCreatePersistedLinkProperty(name, convertFromRealmFieldType(type, required), linkedClassName)); } Property(String name, String sourceClassName, String sourceFieldName) { From 676c6e3db23516ee6d3a9c78d4233c5701d1c125 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 12 Sep 2017 22:33:12 +0300 Subject: [PATCH 28/72] fix implementation of RealmList.remove(Object) --- .../src/main/java/io/realm/RealmList.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 579354b6e1..0bdafd4c52 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -346,14 +346,9 @@ public boolean remove(@Nullable Object object) { throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR); } - if (object != null) { - if (clazz != object.getClass()) { - return false; - } - if (clazz == byte[].class) { - // we need special handling for class since equals against byte[] never matches. - return remove((byte[]) object); - } + if (object instanceof byte[] && clazz == byte[].class) { + // we need special handling for class since equals against byte[] never matches. + return remove((byte[]) object); } return super.remove(object); } From f354cea49e3ec7d0c16e5c4b4447265254a9b1ab Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 12 Sep 2017 22:33:39 +0300 Subject: [PATCH 29/72] fix RealmListTests --- .../src/androidTest/java/io/realm/RealmListTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java index 4f54e2b140..3ac6ad306d 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java @@ -684,12 +684,12 @@ public void where_afterContainerObjectRemoved() { @Test public void toString_AfterContainerObjectRemoved() { RealmList dogs = createDeletedRealmList(); - assertEquals("Dog@[invalid]", dogs.toString()); + assertEquals("RealmList@[invalid]", dogs.toString()); } @Test public void toString_managedMode() { - StringBuilder sb = new StringBuilder("Dog@["); + StringBuilder sb = new StringBuilder("RealmList@["); for (int i = 0; i < collection.size() - 1; i++) { sb.append(((RealmObjectProxy) (collection.get(i))).realmGet$proxyState().getRow$realm().getIndex()); sb.append(","); From 57be25fcfb5fd3403a77d30fedf50dde0f7e3147 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 12 Sep 2017 23:20:06 +0300 Subject: [PATCH 30/72] fix RealmListTests --- .../src/androidTest/java/io/realm/RealmListTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java index 3ac6ad306d..d625dac44b 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java @@ -894,6 +894,7 @@ public void add_set_withWrongDynamicObjectType() { dynamicRealm.beginTransaction(); RealmList list = dynamicRealm.createObject(Owner.CLASS_NAME) .getList(Owner.FIELD_DOGS); + list.add(dynamicRealm.createObject(Dog.CLASS_NAME)); DynamicRealmObject dynCat = dynamicRealm.createObject(Cat.CLASS_NAME); try { @@ -934,6 +935,7 @@ public void add_set_dynamicObjectCreatedFromTypedRealm() { dynamicRealm.beginTransaction(); RealmList list = dynamicRealm.createObject(Owner.CLASS_NAME) .getList(Owner.FIELD_DOGS); + list.add(dynamicRealm.createObject(Dog.CLASS_NAME)); try { list.add(dynDog); From 4211526cf85d38645ba69e729b4a541aa6077f88 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 13 Sep 2017 09:05:52 +0300 Subject: [PATCH 31/72] added tests for 'copyToRealm()' and 'copyFromRealm()' --- .../java/io/realm/RealmObjectTests.java | 2 +- .../androidTest/java/io/realm/RealmTests.java | 161 +++++++++++++++- .../java/io/realm/entities/AllTypes.java | 76 +++++++- .../io/realm/entities/AllTypesPrimaryKey.java | 64 +++++++ .../realm/entities/DefaultValueOfField.java | 175 ++++++++++++++---- 5 files changed, 438 insertions(+), 40 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmObjectTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmObjectTests.java index 7ece4e46b1..f396a8ccae 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmObjectTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmObjectTests.java @@ -115,7 +115,7 @@ public void row_isValid() { realm.commitTransaction(); assertNotNull("RealmObject.realmGetRow returns zero ", row); - assertEquals(10, row.getColumnCount()); + assertEquals(17, row.getColumnCount()); } @Test diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java index 6485e6ed5c..197db26252 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java @@ -64,8 +64,6 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.Nullable; - import io.realm.entities.AllJavaTypes; import io.realm.entities.AllTypes; import io.realm.entities.AllTypesPrimaryKey; @@ -120,7 +118,6 @@ import static io.realm.internal.test.ExtraTests.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; @@ -132,7 +129,6 @@ import static org.mockito.Mockito.when; - @RunWith(AndroidJUnit4.class) public class RealmTests { private final static int TEST_DATA_SIZE = 10; @@ -1304,6 +1300,14 @@ public void copyToRealm() { allTypes.setColumnRealmObject(dog); allTypes.setColumnRealmList(list); + allTypes.setColumnStringList(new RealmList("1")); + allTypes.setColumnBinaryList(new RealmList(new byte[] {1})); + allTypes.setColumnBooleanList(new RealmList(true)); + allTypes.setColumnLongList(new RealmList(1L)); + allTypes.setColumnDoubleList(new RealmList(1D)); + allTypes.setColumnFloatList(new RealmList(1F)); + allTypes.setColumnDateList(new RealmList(new Date(1L))); + realm.beginTransaction(); AllTypes realmTypes = realm.copyToRealm(allTypes); realm.commitTransaction(); @@ -1318,7 +1322,22 @@ public void copyToRealm() { assertArrayEquals(allTypes.getColumnBinary(), realmTypes.getColumnBinary()); assertEquals(allTypes.getColumnRealmObject().getName(), dog.getName()); assertEquals(list.size(), realmTypes.getColumnRealmList().size()); + //noinspection ConstantConditions assertEquals(list.get(0).getName(), realmTypes.getColumnRealmList().get(0).getName()); + assertEquals(1, realmTypes.getColumnStringList().size()); + assertEquals("1", realmTypes.getColumnStringList().get(0)); + assertEquals(1, realmTypes.getColumnBooleanList().size()); + assertEquals(true, realmTypes.getColumnBooleanList().get(0)); + assertEquals(1, realmTypes.getColumnBinaryList().size()); + assertTrue(Arrays.equals(new byte[] {1}, realmTypes.getColumnBinaryList().get(0))); + assertEquals(1, realmTypes.getColumnLongList().size()); + assertEquals((Long) 1L, realmTypes.getColumnLongList().get(0)); + assertEquals(1, realmTypes.getColumnDoubleList().size()); + assertEquals((Double) 1D, realmTypes.getColumnDoubleList().get(0)); + assertEquals(1, realmTypes.getColumnFloatList().size()); + assertEquals((Float) 1F, realmTypes.getColumnFloatList().get(0)); + assertEquals(1, realmTypes.getColumnDateList().size()); + assertEquals(new Date(1), realmTypes.getColumnDateList().get(0)); } @Test @@ -1393,8 +1412,8 @@ public void copyToRealm_cyclicListReferences() { oneCyclicType.setName("One"); CyclicType anotherCyclicType = new CyclicType(); anotherCyclicType.setName("Two"); - oneCyclicType.setObjects(new RealmList(anotherCyclicType)); - anotherCyclicType.setObjects(new RealmList(oneCyclicType)); + oneCyclicType.setObjects(new RealmList<>(anotherCyclicType)); + anotherCyclicType.setObjects(new RealmList<>(oneCyclicType)); realm.beginTransaction(); CyclicType realmObject = realm.copyToRealm(oneCyclicType); @@ -1414,6 +1433,15 @@ public void copyToRealm_convertsNullToDefaultValue() { assertEquals("", realmTypes.getColumnString()); assertEquals(new Date(0), realmTypes.getColumnDate()); assertArrayEquals(new byte[0], realmTypes.getColumnBinary()); + + assertNotNull(realmTypes.getColumnRealmList()); + assertNotNull(realmTypes.getColumnStringList()); + assertNotNull(realmTypes.getColumnBinaryList()); + assertNotNull(realmTypes.getColumnBooleanList()); + assertNotNull(realmTypes.getColumnLongList()); + assertNotNull(realmTypes.getColumnDoubleList()); + assertNotNull(realmTypes.getColumnFloatList()); + assertNotNull(realmTypes.getColumnDateList()); } // Check that using copyToRealm will set the primary key directly instead of first setting @@ -1713,6 +1741,13 @@ public void execute(Realm realm) { obj.setColumnRealmObject(new DogPrimaryKey(1, "Dog1")); obj.setColumnRealmList(new RealmList(new DogPrimaryKey(2, "Dog2"))); obj.setColumnBoxedBoolean(true); + obj.setColumnStringList(new RealmList<>("1")); + obj.setColumnBooleanList(new RealmList<>(false)); + obj.setColumnBinaryList(new RealmList<>(new byte[] {1})); + obj.setColumnLongList(new RealmList<>(1L)); + obj.setColumnDoubleList(new RealmList<>(1D)); + obj.setColumnFloatList(new RealmList<>(1F)); + obj.setColumnDateList(new RealmList<>(new Date(1L))); realm.copyToRealm(obj); AllTypesPrimaryKey obj2 = new AllTypesPrimaryKey(); @@ -1726,6 +1761,13 @@ public void execute(Realm realm) { obj2.setColumnRealmObject(new DogPrimaryKey(3, "Dog3")); obj2.setColumnRealmList(new RealmList(new DogPrimaryKey(4, "Dog4"))); obj2.setColumnBoxedBoolean(false); + obj2.setColumnStringList(new RealmList<>("2", "3")); + obj2.setColumnBooleanList(new RealmList<>(true, false)); + obj2.setColumnBinaryList(new RealmList<>(new byte[] {2}, new byte[] {3})); + obj2.setColumnLongList(new RealmList<>(2L, 3L)); + obj2.setColumnDoubleList(new RealmList<>(2D, 3D)); + obj2.setColumnFloatList(new RealmList<>(2F, 3F)); + obj2.setColumnDateList(new RealmList<>(new Date(2L), new Date(3L))); realm.copyToRealmOrUpdate(obj2); } }); @@ -1745,6 +1787,27 @@ public void execute(Realm realm) { assertEquals(1, obj.getColumnRealmList().size()); assertEquals("Dog4", obj.getColumnRealmList().get(0).getName()); assertFalse(obj.getColumnBoxedBoolean()); + assertEquals(2, obj.getColumnStringList().size()); + assertEquals("2", obj.getColumnStringList().get(0)); + assertEquals("3", obj.getColumnStringList().get(1)); + assertEquals(2, obj.getColumnBooleanList().size()); + assertEquals(true, obj.getColumnBooleanList().get(0)); + assertEquals(false, obj.getColumnBooleanList().get(1)); + assertEquals(2, obj.getColumnBinaryList().size()); + assertTrue(Arrays.equals(new byte[] {2}, obj.getColumnBinaryList().get(0))); + assertTrue(Arrays.equals(new byte[] {3}, obj.getColumnBinaryList().get(1))); + assertEquals(2, obj.getColumnLongList().size()); + assertEquals((Long) 2L, obj.getColumnLongList().get(0)); + assertEquals((Long) 3L, obj.getColumnLongList().get(1)); + assertEquals(2, obj.getColumnDoubleList().size()); + assertEquals((Double) 2D, obj.getColumnDoubleList().get(0)); + assertEquals((Double) 3D, obj.getColumnDoubleList().get(1)); + assertEquals(2, obj.getColumnFloatList().size()); + assertEquals((Float) 2F, obj.getColumnFloatList().get(0)); + assertEquals((Float) 3F, obj.getColumnFloatList().get(1)); + assertEquals(2, obj.getColumnDateList().size()); + assertEquals(new Date(2L), obj.getColumnDateList().get(0)); + assertEquals(new Date(3L), obj.getColumnDateList().get(1)); } @Test @@ -2764,6 +2827,17 @@ public void copyToRealm_defaultValuesAreIgnored() { list.add(listItem); obj.setFieldList(list); + obj.setFieldStringList(new RealmList<>("2", "3")); + obj.setFieldBooleanList(new RealmList<>(true, false)); + obj.setFieldBinaryList(new RealmList<>(new byte[] {2}, new byte[] {3})); + obj.setFieldLongList(new RealmList<>(2L, 3L)); + obj.setFieldIntegerList(new RealmList<>(2, 3)); + obj.setFieldShortList(new RealmList<>((short) 2, (short) 3)); + obj.setFieldByteList(new RealmList<>((byte) 2, (byte) 3)); + obj.setFieldDoubleList(new RealmList<>(2D, 3D)); + obj.setFieldFloatList(new RealmList<>(2F, 3F)); + obj.setFieldDateList(new RealmList<>(new Date(2L), new Date(3L))); + managedObj = realm.copyToRealm(obj); } realm.commitTransaction(); @@ -2786,6 +2860,37 @@ public void copyToRealm_defaultValuesAreIgnored() { assertEquals(1, managedObj.getFieldList().size()); assertEquals(fieldListIntValue, managedObj.getFieldList().first().getFieldInt()); + assertEquals(2, managedObj.getFieldStringList().size()); + assertEquals("2", managedObj.getFieldStringList().get(0)); + assertEquals("3", managedObj.getFieldStringList().get(1)); + assertEquals(2, managedObj.getFieldBooleanList().size()); + assertEquals(true, managedObj.getFieldBooleanList().get(0)); + assertEquals(false, managedObj.getFieldBooleanList().get(1)); + assertEquals(2, managedObj.getFieldBinaryList().size()); + assertTrue(Arrays.equals(new byte[] {2}, managedObj.getFieldBinaryList().get(0))); + assertTrue(Arrays.equals(new byte[] {3}, managedObj.getFieldBinaryList().get(1))); + assertEquals(2, managedObj.getFieldLongList().size()); + assertEquals((Long) 2L, managedObj.getFieldLongList().get(0)); + assertEquals((Long) 3L, managedObj.getFieldLongList().get(1)); + assertEquals(2, managedObj.getFieldIntegerList().size()); + assertEquals((Integer) 2, managedObj.getFieldIntegerList().get(0)); + assertEquals((Integer) 3, managedObj.getFieldIntegerList().get(1)); + assertEquals(2, managedObj.getFieldShortList().size()); + assertEquals((Short) (short) 2, managedObj.getFieldShortList().get(0)); + assertEquals((Short) (short) 3, managedObj.getFieldShortList().get(1)); + assertEquals(2, managedObj.getFieldByteList().size()); + assertEquals((Byte) (byte) 2, managedObj.getFieldByteList().get(0)); + assertEquals((Byte) (byte) 3, managedObj.getFieldByteList().get(1)); + assertEquals(2, managedObj.getFieldDoubleList().size()); + assertEquals((Double) 2D, managedObj.getFieldDoubleList().get(0)); + assertEquals((Double) 3D, managedObj.getFieldDoubleList().get(1)); + assertEquals(2, managedObj.getFieldFloatList().size()); + assertEquals((Float) 2F, managedObj.getFieldFloatList().get(0)); + assertEquals((Float) 3F, managedObj.getFieldFloatList().get(1)); + assertEquals(2, managedObj.getFieldDateList().size()); + assertEquals(new Date(2L), managedObj.getFieldDateList().get(0)); + assertEquals(new Date(3L), managedObj.getFieldDateList().get(1)); + // Makes sure that excess object by default value is not created. assertEquals(2, realm.where(RandomPrimaryKey.class).count()); } @@ -2820,6 +2925,17 @@ public void copyFromRealm_defaultValuesAreIgnored() { list.add(listItem); obj.setFieldList(list); + obj.setFieldStringList(new RealmList<>("2", "3")); + obj.setFieldBooleanList(new RealmList<>(true, false)); + obj.setFieldBinaryList(new RealmList<>(new byte[] {2}, new byte[] {3})); + obj.setFieldLongList(new RealmList<>(2L, 3L)); + obj.setFieldIntegerList(new RealmList<>(2, 3)); + obj.setFieldShortList(new RealmList<>((short) 2, (short) 3)); + obj.setFieldByteList(new RealmList<>((byte) 2, (byte) 3)); + obj.setFieldDoubleList(new RealmList<>(2D, 3D)); + obj.setFieldFloatList(new RealmList<>(2F, 3F)); + obj.setFieldDateList(new RealmList<>(new Date(2L), new Date(3L))); + managedObj = realm.copyToRealm(obj); } realm.commitTransaction(); @@ -2841,7 +2957,39 @@ public void copyFromRealm_defaultValuesAreIgnored() { assertTrue(Arrays.equals(managedObj.getFieldBinary(), copy.getFieldBinary())); assertEquals(managedObj.getFieldObject().getFieldInt(), copy.getFieldObject().getFieldInt()); assertEquals(1, copy.getFieldList().size()); + //noinspection ConstantConditions assertEquals(managedObj.getFieldList().first().getFieldInt(), copy.getFieldList().first().getFieldInt()); + + assertEquals(2, managedObj.getFieldStringList().size()); + assertEquals("2", managedObj.getFieldStringList().get(0)); + assertEquals("3", managedObj.getFieldStringList().get(1)); + assertEquals(2, managedObj.getFieldBooleanList().size()); + assertEquals(true, managedObj.getFieldBooleanList().get(0)); + assertEquals(false, managedObj.getFieldBooleanList().get(1)); + assertEquals(2, managedObj.getFieldBinaryList().size()); + assertTrue(Arrays.equals(new byte[] {2}, managedObj.getFieldBinaryList().get(0))); + assertTrue(Arrays.equals(new byte[] {3}, managedObj.getFieldBinaryList().get(1))); + assertEquals(2, managedObj.getFieldLongList().size()); + assertEquals((Long) 2L, managedObj.getFieldLongList().get(0)); + assertEquals((Long) 3L, managedObj.getFieldLongList().get(1)); + assertEquals(2, managedObj.getFieldIntegerList().size()); + assertEquals((Integer) 2, managedObj.getFieldIntegerList().get(0)); + assertEquals((Integer) 3, managedObj.getFieldIntegerList().get(1)); + assertEquals(2, managedObj.getFieldShortList().size()); + assertEquals((Short) (short) 2, managedObj.getFieldShortList().get(0)); + assertEquals((Short) (short) 3, managedObj.getFieldShortList().get(1)); + assertEquals(2, managedObj.getFieldByteList().size()); + assertEquals((Byte) (byte) 2, managedObj.getFieldByteList().get(0)); + assertEquals((Byte) (byte) 3, managedObj.getFieldByteList().get(1)); + assertEquals(2, managedObj.getFieldDoubleList().size()); + assertEquals((Double) 2D, managedObj.getFieldDoubleList().get(0)); + assertEquals((Double) 3D, managedObj.getFieldDoubleList().get(1)); + assertEquals(2, managedObj.getFieldFloatList().size()); + assertEquals((Float) 2F, managedObj.getFieldFloatList().get(0)); + assertEquals((Float) 3F, managedObj.getFieldFloatList().get(1)); + assertEquals(2, managedObj.getFieldDateList().size()); + assertEquals(new Date(2L), managedObj.getFieldDateList().get(0)); + assertEquals(new Date(3L), managedObj.getFieldDateList().get(1)); } // Tests close Realm in another thread different from where it is created. @@ -4157,6 +4305,7 @@ public void init_waitForFilesDir() throws NoSuchMethodException, InvocationTarge when(mockContext.getFilesDir()).then(new Answer() { int calls = 0; File userFolder = tmpFolder.newFolder(); + @Override public File answer(InvocationOnMock invocationOnMock) throws Throwable { calls++; diff --git a/realm/realm-library/src/androidTest/java/io/realm/entities/AllTypes.java b/realm/realm-library/src/androidTest/java/io/realm/entities/AllTypes.java index 5e7d80bacc..f4322445aa 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/entities/AllTypes.java +++ b/realm/realm-library/src/androidTest/java/io/realm/entities/AllTypes.java @@ -37,8 +37,18 @@ public class AllTypes extends RealmObject { public static final String FIELD_REALMOBJECT = "columnRealmObject"; public static final String FIELD_REALMLIST = "columnRealmList"; + public static final String FIELD_STRING_LIST = "columnStringList"; + public static final String FIELD_BINARY_LIST = "columnBinaryList"; + public static final String FIELD_BOOLEAN_LIST = "columnBooleanList"; + public static final String FIELD_LONG_LIST = "columnLongList"; + public static final String FIELD_DOUBLE_LIST = "columnDoubleList"; + public static final String FIELD_FLOAT_LIST = "columnFloatList"; + public static final String FIELD_DATE_LIST = "columnDateList"; + public static final String[] INVALID_TYPES_FIELDS_FOR_DISTINCT - = new String[] {FIELD_REALMOBJECT, FIELD_REALMLIST, FIELD_DOUBLE, FIELD_FLOAT}; + = new String[] {FIELD_REALMOBJECT, FIELD_REALMLIST, FIELD_DOUBLE, FIELD_FLOAT, + FIELD_STRING_LIST, FIELD_BINARY_LIST, FIELD_BOOLEAN_LIST, FIELD_LONG_LIST, + FIELD_DOUBLE_LIST, FIELD_FLOAT_LIST, FIELD_DATE_LIST}; @Required private String columnString = ""; @@ -55,6 +65,14 @@ public class AllTypes extends RealmObject { private Dog columnRealmObject; private RealmList columnRealmList; + private RealmList columnStringList; + private RealmList columnBinaryList; + private RealmList columnBooleanList; + private RealmList columnLongList; + private RealmList columnDoubleList; + private RealmList columnFloatList; + private RealmList columnDateList; + public String getColumnString() { return columnString; } @@ -130,4 +148,60 @@ public RealmList getColumnRealmList() { public void setColumnRealmList(RealmList columnRealmList) { this.columnRealmList = columnRealmList; } + + public RealmList getColumnStringList() { + return columnStringList; + } + + public void setColumnStringList(RealmList columnStringList) { + this.columnStringList = columnStringList; + } + + public RealmList getColumnBinaryList() { + return columnBinaryList; + } + + public void setColumnBinaryList(RealmList columnBinaryList) { + this.columnBinaryList = columnBinaryList; + } + + public RealmList getColumnBooleanList() { + return columnBooleanList; + } + + public void setColumnBooleanList(RealmList columnBooleanList) { + this.columnBooleanList = columnBooleanList; + } + + public RealmList getColumnLongList() { + return columnLongList; + } + + public void setColumnLongList(RealmList columnLongList) { + this.columnLongList = columnLongList; + } + + public RealmList getColumnDoubleList() { + return columnDoubleList; + } + + public void setColumnDoubleList(RealmList columnDoubleList) { + this.columnDoubleList = columnDoubleList; + } + + public RealmList getColumnFloatList() { + return columnFloatList; + } + + public void setColumnFloatList(RealmList columnFloatList) { + this.columnFloatList = columnFloatList; + } + + public RealmList getColumnDateList() { + return columnDateList; + } + + public void setColumnDateList(RealmList columnDateList) { + this.columnDateList = columnDateList; + } } diff --git a/realm/realm-library/src/androidTest/java/io/realm/entities/AllTypesPrimaryKey.java b/realm/realm-library/src/androidTest/java/io/realm/entities/AllTypesPrimaryKey.java index 5965b6d031..c6bff3fda0 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/entities/AllTypesPrimaryKey.java +++ b/realm/realm-library/src/androidTest/java/io/realm/entities/AllTypesPrimaryKey.java @@ -35,6 +35,14 @@ public class AllTypesPrimaryKey extends RealmObject { private RealmList columnRealmList; private Boolean columnBoxedBoolean; + private RealmList columnStringList; + private RealmList columnBinaryList; + private RealmList columnBooleanList; + private RealmList columnLongList; + private RealmList columnDoubleList; + private RealmList columnFloatList; + private RealmList columnDateList; + public String getColumnString() { return columnString; } @@ -114,4 +122,60 @@ public Boolean getColumnBoxedBoolean() { public void setColumnBoxedBoolean(Boolean columnBoxedBoolean) { this.columnBoxedBoolean = columnBoxedBoolean; } + + public RealmList getColumnStringList() { + return columnStringList; + } + + public void setColumnStringList(RealmList columnStringList) { + this.columnStringList = columnStringList; + } + + public RealmList getColumnBinaryList() { + return columnBinaryList; + } + + public void setColumnBinaryList(RealmList columnBinaryList) { + this.columnBinaryList = columnBinaryList; + } + + public RealmList getColumnBooleanList() { + return columnBooleanList; + } + + public void setColumnBooleanList(RealmList columnBooleanList) { + this.columnBooleanList = columnBooleanList; + } + + public RealmList getColumnLongList() { + return columnLongList; + } + + public void setColumnLongList(RealmList columnLongList) { + this.columnLongList = columnLongList; + } + + public RealmList getColumnDoubleList() { + return columnDoubleList; + } + + public void setColumnDoubleList(RealmList columnDoubleList) { + this.columnDoubleList = columnDoubleList; + } + + public RealmList getColumnFloatList() { + return columnFloatList; + } + + public void setColumnFloatList(RealmList columnFloatList) { + this.columnFloatList = columnFloatList; + } + + public RealmList getColumnDateList() { + return columnDateList; + } + + public void setColumnDateList(RealmList columnDateList) { + this.columnDateList = columnDateList; + } } diff --git a/realm/realm-library/src/androidTest/java/io/realm/entities/DefaultValueOfField.java b/realm/realm-library/src/androidTest/java/io/realm/entities/DefaultValueOfField.java index 0378e64817..c9e13697d3 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/entities/DefaultValueOfField.java +++ b/realm/realm-library/src/androidTest/java/io/realm/entities/DefaultValueOfField.java @@ -27,42 +27,63 @@ public class DefaultValueOfField extends RealmObject { public static final String CLASS_NAME = "DefaultValueOfField"; - public static String FIELD_IGNORED = "fieldIgnored"; - public static String FIELD_RANDOM_STRING = "fieldRandomString"; - public static String FIELD_STRING = "fieldString"; - public static String FIELD_SHORT = "fieldShort"; - public static String FIELD_INT = "fieldInt"; - public static String FIELD_LONG_PRIMARY_KEY = "fieldLongPrimaryKey"; - public static String FIELD_LONG = "fieldLong"; - public static String FIELD_BYTE = "fieldByte"; - public static String FIELD_FLOAT = "fieldFloat"; - public static String FIELD_DOUBLE = "fieldDouble"; - public static String FIELD_BOOLEAN = "fieldBoolean"; - public static String FIELD_DATE = "fieldDate"; - public static String FIELD_BINARY = "fieldBinary"; - public static String FIELD_OBJECT = "fieldObject"; - public static String FIELD_LIST = "fieldList"; - - - public static String FIELD_IGNORED_DEFAULT_VALUE = "ignored"; - public static String FIELD_STRING_DEFAULT_VALUE = "defaultString"; - public static short FIELD_SHORT_DEFAULT_VALUE = 1234; - public static int FIELD_INT_DEFAULT_VALUE = 123456; - public static long FIELD_LONG_PRIMARY_KEY_DEFAULT_VALUE = 2L * Integer.MAX_VALUE; - public static long FIELD_LONG_DEFAULT_VALUE = 3L * Integer.MAX_VALUE; - public static byte FIELD_BYTE_DEFAULT_VALUE = 100; - public static float FIELD_FLOAT_DEFAULT_VALUE = 0.5f; - public static double FIELD_DOUBLE_DEFAULT_VALUE = 0.25; - public static boolean FIELD_BOOLEAN_DEFAULT_VALUE = true; - public static Date FIELD_DATE_DEFAULT_VALUE = new Date(1473691826000L /*2016/9/12 23:56:26 JST*/); - public static byte[] FIELD_BINARY_DEFAULT_VALUE = new byte[] {123, -100, 0, 2}; - public static RandomPrimaryKey FIELD_OBJECT_DEFAULT_VALUE; - public static RealmList FIELD_LIST_DEFAULT_VALUE; + public static final String FIELD_IGNORED = "fieldIgnored"; + public static final String FIELD_RANDOM_STRING = "fieldRandomString"; + public static final String FIELD_STRING = "fieldString"; + public static final String FIELD_SHORT = "fieldShort"; + public static final String FIELD_INT = "fieldInt"; + public static final String FIELD_LONG_PRIMARY_KEY = "fieldLongPrimaryKey"; + public static final String FIELD_LONG = "fieldLong"; + public static final String FIELD_BYTE = "fieldByte"; + public static final String FIELD_FLOAT = "fieldFloat"; + public static final String FIELD_DOUBLE = "fieldDouble"; + public static final String FIELD_BOOLEAN = "fieldBoolean"; + public static final String FIELD_DATE = "fieldDate"; + public static final String FIELD_BINARY = "fieldBinary"; + public static final String FIELD_OBJECT = "fieldObject"; + public static final String FIELD_LIST = "fieldList"; + + + public static final String FIELD_IGNORED_DEFAULT_VALUE = "ignored"; + public static final String FIELD_STRING_DEFAULT_VALUE = "defaultString"; + public static final short FIELD_SHORT_DEFAULT_VALUE = 1234; + public static final int FIELD_INT_DEFAULT_VALUE = 123456; + public static final long FIELD_LONG_PRIMARY_KEY_DEFAULT_VALUE = 2L * Integer.MAX_VALUE; + public static final long FIELD_LONG_DEFAULT_VALUE = 3L * Integer.MAX_VALUE; + public static final byte FIELD_BYTE_DEFAULT_VALUE = 100; + public static final float FIELD_FLOAT_DEFAULT_VALUE = 0.5f; + public static final double FIELD_DOUBLE_DEFAULT_VALUE = 0.25; + public static final boolean FIELD_BOOLEAN_DEFAULT_VALUE = true; + public static final Date FIELD_DATE_DEFAULT_VALUE = new Date(1473691826000L /*2016/9/12 23:56:26 JST*/); + public static final byte[] FIELD_BINARY_DEFAULT_VALUE = new byte[] {123, -100, 0, 2}; + public static final RandomPrimaryKey FIELD_OBJECT_DEFAULT_VALUE; + public static final RealmList FIELD_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_STRING_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_BOOLEAN_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_BINARY_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_LONG_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_INTEGER_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_SHORT_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_BYTE_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_DOUBLE_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_FLOAT_LIST_DEFAULT_VALUE; + public static final RealmList FIELD_DATE_LIST_DEFAULT_VALUE; static { FIELD_OBJECT_DEFAULT_VALUE = new RandomPrimaryKey(); FIELD_LIST_DEFAULT_VALUE = new RealmList(); FIELD_LIST_DEFAULT_VALUE.add(new RandomPrimaryKey()); + + FIELD_STRING_LIST_DEFAULT_VALUE = new RealmList<>("1"); + FIELD_BOOLEAN_LIST_DEFAULT_VALUE = new RealmList<>(true); + FIELD_BINARY_LIST_DEFAULT_VALUE = new RealmList<>(new byte[] {1}); + FIELD_LONG_LIST_DEFAULT_VALUE = new RealmList<>(1L); + FIELD_INTEGER_LIST_DEFAULT_VALUE = new RealmList<>(1); + FIELD_SHORT_LIST_DEFAULT_VALUE = new RealmList<>((short) 1); + FIELD_BYTE_LIST_DEFAULT_VALUE = new RealmList<>((byte) 1); + FIELD_DOUBLE_LIST_DEFAULT_VALUE = new RealmList<>(1D); + FIELD_FLOAT_LIST_DEFAULT_VALUE = new RealmList<>(1F); + FIELD_DATE_LIST_DEFAULT_VALUE = new RealmList<>(new Date(1)); } public static String lastRandomStringValue; @@ -83,8 +104,18 @@ public class DefaultValueOfField extends RealmObject { private RandomPrimaryKey fieldObject = FIELD_OBJECT_DEFAULT_VALUE; private RealmList fieldList = FIELD_LIST_DEFAULT_VALUE; - public DefaultValueOfField() { + private RealmList fieldStringList = FIELD_STRING_LIST_DEFAULT_VALUE; + private RealmList fieldBinaryList = FIELD_BINARY_LIST_DEFAULT_VALUE; + private RealmList fieldBooleanList = FIELD_BOOLEAN_LIST_DEFAULT_VALUE; + private RealmList fieldLongList = FIELD_LONG_LIST_DEFAULT_VALUE; + private RealmList fieldIntegerList = FIELD_INTEGER_LIST_DEFAULT_VALUE; + private RealmList fieldShortList = FIELD_SHORT_LIST_DEFAULT_VALUE; + private RealmList fieldByteList = FIELD_BYTE_LIST_DEFAULT_VALUE; + private RealmList fieldDoubleList = FIELD_DOUBLE_LIST_DEFAULT_VALUE; + private RealmList fieldFloatList = FIELD_FLOAT_LIST_DEFAULT_VALUE; + private RealmList fieldDateList = FIELD_DATE_LIST_DEFAULT_VALUE; + public DefaultValueOfField() { } public DefaultValueOfField(long fieldLong) { @@ -210,4 +241,84 @@ public RealmList getFieldList() { public void setFieldList(RealmList fieldList) { this.fieldList = fieldList; } + + public RealmList getFieldStringList() { + return fieldStringList; + } + + public void setFieldStringList(RealmList fieldStringList) { + this.fieldStringList = fieldStringList; + } + + public RealmList getFieldBinaryList() { + return fieldBinaryList; + } + + public void setFieldBinaryList(RealmList fieldBinaryList) { + this.fieldBinaryList = fieldBinaryList; + } + + public RealmList getFieldBooleanList() { + return fieldBooleanList; + } + + public void setFieldBooleanList(RealmList fieldBooleanList) { + this.fieldBooleanList = fieldBooleanList; + } + + public RealmList getFieldLongList() { + return fieldLongList; + } + + public void setFieldLongList(RealmList fieldLongList) { + this.fieldLongList = fieldLongList; + } + + public RealmList getFieldIntegerList() { + return fieldIntegerList; + } + + public void setFieldIntegerList(RealmList fieldIntegerList) { + this.fieldIntegerList = fieldIntegerList; + } + + public RealmList getFieldShortList() { + return fieldShortList; + } + + public void setFieldShortList(RealmList fieldShortList) { + this.fieldShortList = fieldShortList; + } + + public RealmList getFieldByteList() { + return fieldByteList; + } + + public void setFieldByteList(RealmList fieldByteList) { + this.fieldByteList = fieldByteList; + } + + public RealmList getFieldDoubleList() { + return fieldDoubleList; + } + + public void setFieldDoubleList(RealmList fieldDoubleList) { + this.fieldDoubleList = fieldDoubleList; + } + + public RealmList getFieldFloatList() { + return fieldFloatList; + } + + public void setFieldFloatList(RealmList fieldFloatList) { + this.fieldFloatList = fieldFloatList; + } + + public RealmList getFieldDateList() { + return fieldDateList; + } + + public void setFieldDateList(RealmList fieldDateList) { + this.fieldDateList = fieldDateList; + } } From f4c75f67be586e0234a4a33ccf028624316dfa92 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 13 Sep 2017 09:06:16 +0300 Subject: [PATCH 32/72] added tests for non-null primitive list --- .../realm/ManagedRealmListForValueTests.java | 54 +++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index 0025990be9..b8895e1cd4 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -956,7 +956,57 @@ public void deleteAllFromRealm_invalidListShouldThrow() { } @Test - @Ignore + public void add_null_nonNullableListThrows() { + if (typeIsNullable) { + return; + } + + realm.beginTransaction(); + final int initialSize = list.size(); + try { + //thrown.expect(IllegalArgumentException.class); + //noinspection unchecked + list.add(null); + } finally { + assertEquals(initialSize, list.size()); + } + } + + @Test + public void addAt_null_nonNullableListThrows() { + if (typeIsNullable) { + return; + } + + realm.beginTransaction(); + final int initialSize = list.size(); + try { + thrown.expect(IllegalArgumentException.class); + //noinspection unchecked + list.add(1, null); + } finally { + assertEquals(initialSize, list.size()); + } + } + + @Test + public void set_null_nonNullableListThrows() { + if (typeIsNullable) { + return; + } + + realm.beginTransaction(); + final int initialSize = list.size(); + try { + thrown.expect(IllegalArgumentException.class); + //noinspection unchecked + list.set(0, null); + } finally { + assertEquals(initialSize, list.size()); + } + } + + @Test @RunTestInLooperThread public void changeListener_forAddObject() { Realm realm = looperThread.getRealm(); @@ -1206,7 +1256,6 @@ public void onChange(RealmList element) { } @Test - @Ignore("unexpected native crash") @RunTestInLooperThread public void changeListener_forRemoveAll() { Realm realm = looperThread.getRealm(); @@ -1308,7 +1357,6 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch } @Test - @Ignore("unexpected native crash") @RunTestInLooperThread public void changeListener_forDeleteAll() { Realm realm = looperThread.getRealm(); From d48107a59c5c65a701f95cfe7c5eee183e8caed5 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 13 Sep 2017 09:10:17 +0300 Subject: [PATCH 33/72] fix test --- .../java/io/realm/ManagedRealmListForValueTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index b8895e1cd4..c56a07df81 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -964,7 +964,7 @@ public void add_null_nonNullableListThrows() { realm.beginTransaction(); final int initialSize = list.size(); try { - //thrown.expect(IllegalArgumentException.class); + thrown.expect(IllegalArgumentException.class); //noinspection unchecked list.add(null); } finally { From e6549f747f8a2d7851045c7c3766174b58cee705 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Wed, 13 Sep 2017 12:13:44 +0300 Subject: [PATCH 34/72] use OsObjectSchemaInfo.addPersistedValueListProperty() --- .../processor/RealmProxyClassGenerator.java | 8 ++-- .../io/realm/AllTypesRealmProxy.java | 24 +++++------ .../io/realm/NullTypesRealmProxy.java | 42 +++++++++---------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 6e14d242f6..ed2dbd2089 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -726,14 +726,14 @@ private void emitCreateExpectedObjectSchemaInfo(JavaWriter writer) throws IOExce case OBJECT: String fieldTypeSimpleName = Utils.getFieldTypeSimpleName(field); - writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.OBJECT, \"%s\", !Property.REQUIRED)", + writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.OBJECT, \"%s\")", fieldName, fieldTypeSimpleName); break; case LIST: // only for model list. String genericTypeSimpleName = Utils.getGenericTypeSimpleName(field); - writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.LIST, \"%s\", !Property.REQUIRED)", + writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", RealmFieldType.LIST, \"%s\")", fieldName, genericTypeSimpleName); break; @@ -744,8 +744,8 @@ private void emitCreateExpectedObjectSchemaInfo(JavaWriter writer) throws IOExce case DATE_LIST: case FLOAT_LIST: case DOUBLE_LIST: - writer.emitStatement("builder.addPersistedLinkProperty(\"%s\", %s, \"%s\", %s)", - fieldName, fieldType.getRealmType(), "", metadata.isElementNullable(field) ? "!Property.REQUIRED" : "Property.REQUIRED"); + writer.emitStatement("builder.addPersistedValueListProperty(\"%s\", %s, %s)", + fieldName, fieldType.getRealmType(), metadata.isElementNullable(field) ? "!Property.REQUIRED" : "Property.REQUIRED"); break; case BACKLINK: diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index 89bc5d08ee..f901c9e6be 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -869,18 +869,18 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { builder.addPersistedProperty("columnDate", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED); builder.addPersistedProperty("columnBinary", RealmFieldType.BINARY, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED); builder.addPersistedProperty("columnMutableRealmInteger", RealmFieldType.INTEGER, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); - builder.addPersistedLinkProperty("columnObject", RealmFieldType.OBJECT, "AllTypes", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnRealmList", RealmFieldType.LIST, "AllTypes", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnStringList", RealmFieldType.STRING_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnBinaryList", RealmFieldType.BINARY_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnBooleanList", RealmFieldType.BOOLEAN_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnLongList", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnIntegerList", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnShortList", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnByteList", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnDoubleList", RealmFieldType.DOUBLE_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnFloatList", RealmFieldType.FLOAT_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("columnDateList", RealmFieldType.DATE_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("columnObject", RealmFieldType.OBJECT, "AllTypes"); + builder.addPersistedLinkProperty("columnRealmList", RealmFieldType.LIST, "AllTypes"); + builder.addPersistedValueListProperty("columnStringList", RealmFieldType.STRING_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnBinaryList", RealmFieldType.BINARY_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnBooleanList", RealmFieldType.BOOLEAN_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnLongList", RealmFieldType.INTEGER_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnIntegerList", RealmFieldType.INTEGER_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnShortList", RealmFieldType.INTEGER_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnByteList", RealmFieldType.INTEGER_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnDoubleList", RealmFieldType.DOUBLE_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnFloatList", RealmFieldType.FLOAT_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("columnDateList", RealmFieldType.DATE_LIST, !Property.REQUIRED); builder.addComputedLinkProperty("parentObjects", "AllTypes", "columnObject"); return builder.build(); } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index 451180b310..8dc5f74452 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -1728,27 +1728,27 @@ private static OsObjectSchemaInfo createExpectedObjectSchemaInfo() { builder.addPersistedProperty("fieldDoubleNull", RealmFieldType.DOUBLE, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); builder.addPersistedProperty("fieldDateNotNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, Property.REQUIRED); builder.addPersistedProperty("fieldDateNull", RealmFieldType.DATE, !Property.PRIMARY_KEY, !Property.INDEXED, !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldObjectNull", RealmFieldType.OBJECT, "NullTypes", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldStringListNotNull", RealmFieldType.STRING_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldStringListNull", RealmFieldType.STRING_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldBinaryListNotNull", RealmFieldType.BINARY_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldBinaryListNull", RealmFieldType.BINARY_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldBooleanListNotNull", RealmFieldType.BOOLEAN_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldBooleanListNull", RealmFieldType.BOOLEAN_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldLongListNotNull", RealmFieldType.INTEGER_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldLongListNull", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldIntegerListNotNull", RealmFieldType.INTEGER_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldIntegerListNull", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldShortListNotNull", RealmFieldType.INTEGER_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldShortListNull", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldByteListNotNull", RealmFieldType.INTEGER_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldByteListNull", RealmFieldType.INTEGER_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldDoubleListNotNull", RealmFieldType.DOUBLE_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldDoubleListNull", RealmFieldType.DOUBLE_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldFloatListNotNull", RealmFieldType.FLOAT_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldFloatListNull", RealmFieldType.FLOAT_LIST, "", !Property.REQUIRED); - builder.addPersistedLinkProperty("fieldDateListNotNull", RealmFieldType.DATE_LIST, "", Property.REQUIRED); - builder.addPersistedLinkProperty("fieldDateListNull", RealmFieldType.DATE_LIST, "", !Property.REQUIRED); + builder.addPersistedLinkProperty("fieldObjectNull", RealmFieldType.OBJECT, "NullTypes"); + builder.addPersistedValueListProperty("fieldStringListNotNull", RealmFieldType.STRING_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldStringListNull", RealmFieldType.STRING_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldBinaryListNotNull", RealmFieldType.BINARY_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldBinaryListNull", RealmFieldType.BINARY_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldBooleanListNotNull", RealmFieldType.BOOLEAN_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldBooleanListNull", RealmFieldType.BOOLEAN_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldLongListNotNull", RealmFieldType.INTEGER_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldLongListNull", RealmFieldType.INTEGER_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldIntegerListNotNull", RealmFieldType.INTEGER_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldIntegerListNull", RealmFieldType.INTEGER_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldShortListNotNull", RealmFieldType.INTEGER_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldShortListNull", RealmFieldType.INTEGER_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldByteListNotNull", RealmFieldType.INTEGER_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldByteListNull", RealmFieldType.INTEGER_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldDoubleListNotNull", RealmFieldType.DOUBLE_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldDoubleListNull", RealmFieldType.DOUBLE_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldFloatListNotNull", RealmFieldType.FLOAT_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldFloatListNull", RealmFieldType.FLOAT_LIST, !Property.REQUIRED); + builder.addPersistedValueListProperty("fieldDateListNotNull", RealmFieldType.DATE_LIST, Property.REQUIRED); + builder.addPersistedValueListProperty("fieldDateListNull", RealmFieldType.DATE_LIST, !Property.REQUIRED); return builder.build(); } From 65cb83cbcc22a012347fc8fd4109a1a049d2d640 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 00:43:32 +0300 Subject: [PATCH 35/72] fix test --- .../src/androidTest/java/io/realm/RealmSchemaTests.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmSchemaTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmSchemaTests.java index 3bc7d1b6b9..1ad00d0e49 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmSchemaTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmSchemaTests.java @@ -600,8 +600,10 @@ public void schemaInformationOfPrimitiveLists() { final RealmFieldType expectedType = entry.getValue(); assertEquals(expectedType, objectSchema.getFieldType(fieldName)); - assertEquals(!fieldName.endsWith("_NOT_NULL"), objectSchema.isNullable(fieldName)); - assertEquals(fieldName.endsWith("_NOT_NULL"), objectSchema.isRequired(fieldName)); + assertEquals("isNullable('" + fieldName + "')", + !fieldName.endsWith("NotNull"), objectSchema.isNullable(fieldName)); + assertEquals("isRequired('" + fieldName + "')", + fieldName.endsWith("NotNull"), objectSchema.isRequired(fieldName)); assertFalse(objectSchema.isPrimaryKey(fieldName)); } } From 69fbdf5aa260f765521b1032c4a210d9d3143cff Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 01:22:07 +0300 Subject: [PATCH 36/72] introduce Row.getModelList() and Row.getValueList() to check field type more precisely --- .../processor/RealmProxyClassGenerator.java | 30 ++++--- .../main/java/io/realm/processor/Utils.java | 9 +++ .../io/realm/AllTypesRealmProxy.java | 44 +++++----- .../io/realm/NullTypesRealmProxy.java | 80 +++++++++---------- .../java/io/realm/internal/CheckedRow.java | 23 +++++- .../java/io/realm/internal/InvalidRow.java | 10 +++ .../java/io/realm/internal/PendingRow.java | 10 +++ .../src/main/java/io/realm/internal/Row.java | 5 ++ .../java/io/realm/internal/UncheckedRow.java | 10 +++ 9 files changed, 148 insertions(+), 73 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index ed2dbd2089..243f166ea7 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -505,7 +505,7 @@ public void emit(JavaWriter writer) throws IOException { //@formatter:on /** - * LinkLists + * ModelList, ValueList */ //@formatter:off private void emitRealmList( @@ -524,9 +524,15 @@ private void emitRealmList( .emitSingleLineComment("use the cached value if available") .beginControlFlow("if (" + fieldName + "RealmList != null)") .emitStatement("return " + fieldName + "RealmList") - .nextControlFlow("else") - .emitStatement("OsList osList = proxyState.getRow$realm().getList(%s)", fieldIndexVariableReference(field)) - .emitStatement(fieldName + "RealmList = new RealmList<%s>(%s.class, osList, proxyState.getRealm$realm())", + .nextControlFlow("else"); + if (Utils.isRealmModelList(field)) { + writer.emitStatement("OsList osList = proxyState.getRow$realm().getModelList(%s)", + fieldIndexVariableReference(field)); + } else { + writer.emitStatement("OsList osList = proxyState.getRow$realm().getValueList(%1$s, RealmFieldType.%2$s)", + fieldIndexVariableReference(field), Utils.getValueListFieldType(field).name()); + } + writer.emitStatement(fieldName + "RealmList = new RealmList<%s>(%s.class, osList, proxyState.getRealm$realm())", genericType, genericType) .emitStatement("return " + fieldName + "RealmList") .endControlFlow() @@ -566,9 +572,15 @@ public void emit(JavaWriter writer) throws IOException { // LinkView currently does not support default value feature. Just fallback to normal code. } }); - writer.emitStatement("proxyState.getRealm$realm().checkIfValid()") - .emitStatement("OsList osList = proxyState.getRow$realm().getList(%s)", fieldIndexVariableReference(field)) - .emitStatement("osList.removeAll()") + writer.emitStatement("proxyState.getRealm$realm().checkIfValid()"); + if (Utils.isRealmModelList(field)) { + writer.emitStatement("OsList osList = proxyState.getRow$realm().getModelList(%s)", + fieldIndexVariableReference(field)); + } else { + writer.emitStatement("OsList osList = proxyState.getRow$realm().getValueList(%1$s, RealmFieldType.%2$s)", + fieldIndexVariableReference(field), Utils.getValueListFieldType(field).name()); + } + writer.emitStatement("osList.removeAll()") .beginControlFlow("if (value == null)") .emitStatement("return") .endControlFlow(); @@ -2120,9 +2132,7 @@ private Constants.RealmFieldType getRealmType(VariableElement field) { return Constants.RealmFieldType.LIST; } if (Utils.isRealmValueList(field)) { - final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); - final Constants.RealmFieldType fieldType = - Constants.LIST_ELEMENT_TYPE_TO_REALM_TYPES.get(elementTypeMirror.toString()); + final Constants.RealmFieldType fieldType = Utils.getValueListFieldType(field); if (fieldType == null) { return Constants.RealmFieldType.NOTYPE; } diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java index c572ce29e0..f744a8f12f 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java @@ -174,6 +174,15 @@ public static TypeMirror getRealmListElementTypeMirror(VariableElement field) { return ((DeclaredType) field.asType()).getTypeArguments().get(0); } + /** + * @param field {@link VariableElement} of a value list field. + * @return element type of the list field. + */ + public static Constants.RealmFieldType getValueListFieldType(VariableElement field) { + final TypeMirror elementTypeMirror = getRealmListElementTypeMirror(field); + return Constants.LIST_ELEMENT_TYPE_TO_REALM_TYPES.get(elementTypeMirror.toString()); + } + /** * @return {@code true} if a given field type is {@code RealmList} and its element type is {@Code RealmObject}, * {@code false} otherwise. diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index f901c9e6be..7afb2b950f 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -411,7 +411,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnRealmListRealmList != null) { return columnRealmListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnRealmListIndex); + OsList osList = proxyState.getRow$realm().getModelList(columnInfo.columnRealmListIndex); columnRealmListRealmList = new RealmList(some.test.AllTypes.class, osList, proxyState.getRealm$realm()); return columnRealmListRealmList; } @@ -442,7 +442,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnRealmListIndex); + OsList osList = proxyState.getRow$realm().getModelList(columnInfo.columnRealmListIndex); osList.removeAll(); if (value == null) { return; @@ -465,7 +465,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnStringListRealmList != null) { return columnStringListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnStringListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnStringListIndex, RealmFieldType.STRING_LIST); columnStringListRealmList = new RealmList(java.lang.String.class, osList, proxyState.getRealm$realm()); return columnStringListRealmList; } @@ -483,7 +483,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnStringListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnStringListIndex, RealmFieldType.STRING_LIST); osList.removeAll(); if (value == null) { return; @@ -504,7 +504,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnBinaryListRealmList != null) { return columnBinaryListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnBinaryListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnBinaryListIndex, RealmFieldType.BINARY_LIST); columnBinaryListRealmList = new RealmList(byte[].class, osList, proxyState.getRealm$realm()); return columnBinaryListRealmList; } @@ -522,7 +522,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnBinaryListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnBinaryListIndex, RealmFieldType.BINARY_LIST); osList.removeAll(); if (value == null) { return; @@ -543,7 +543,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnBooleanListRealmList != null) { return columnBooleanListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnBooleanListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnBooleanListIndex, RealmFieldType.BOOLEAN_LIST); columnBooleanListRealmList = new RealmList(java.lang.Boolean.class, osList, proxyState.getRealm$realm()); return columnBooleanListRealmList; } @@ -561,7 +561,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnBooleanListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnBooleanListIndex, RealmFieldType.BOOLEAN_LIST); osList.removeAll(); if (value == null) { return; @@ -582,7 +582,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnLongListRealmList != null) { return columnLongListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnLongListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnLongListIndex, RealmFieldType.INTEGER_LIST); columnLongListRealmList = new RealmList(java.lang.Long.class, osList, proxyState.getRealm$realm()); return columnLongListRealmList; } @@ -600,7 +600,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnLongListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnLongListIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -621,7 +621,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnIntegerListRealmList != null) { return columnIntegerListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnIntegerListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnIntegerListIndex, RealmFieldType.INTEGER_LIST); columnIntegerListRealmList = new RealmList(java.lang.Integer.class, osList, proxyState.getRealm$realm()); return columnIntegerListRealmList; } @@ -639,7 +639,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnIntegerListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnIntegerListIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -660,7 +660,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnShortListRealmList != null) { return columnShortListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnShortListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnShortListIndex, RealmFieldType.INTEGER_LIST); columnShortListRealmList = new RealmList(java.lang.Short.class, osList, proxyState.getRealm$realm()); return columnShortListRealmList; } @@ -678,7 +678,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnShortListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnShortListIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -699,7 +699,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnByteListRealmList != null) { return columnByteListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnByteListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnByteListIndex, RealmFieldType.INTEGER_LIST); columnByteListRealmList = new RealmList(java.lang.Byte.class, osList, proxyState.getRealm$realm()); return columnByteListRealmList; } @@ -717,7 +717,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnByteListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnByteListIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -738,7 +738,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnDoubleListRealmList != null) { return columnDoubleListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnDoubleListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnDoubleListIndex, RealmFieldType.DOUBLE_LIST); columnDoubleListRealmList = new RealmList(java.lang.Double.class, osList, proxyState.getRealm$realm()); return columnDoubleListRealmList; } @@ -756,7 +756,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnDoubleListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnDoubleListIndex, RealmFieldType.DOUBLE_LIST); osList.removeAll(); if (value == null) { return; @@ -777,7 +777,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnFloatListRealmList != null) { return columnFloatListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnFloatListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnFloatListIndex, RealmFieldType.FLOAT_LIST); columnFloatListRealmList = new RealmList(java.lang.Float.class, osList, proxyState.getRealm$realm()); return columnFloatListRealmList; } @@ -795,7 +795,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnFloatListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnFloatListIndex, RealmFieldType.FLOAT_LIST); osList.removeAll(); if (value == null) { return; @@ -816,7 +816,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (columnDateListRealmList != null) { return columnDateListRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnDateListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnDateListIndex, RealmFieldType.DATE_LIST); columnDateListRealmList = new RealmList(java.util.Date.class, osList, proxyState.getRealm$realm()); return columnDateListRealmList; } @@ -834,7 +834,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.columnDateListIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.columnDateListIndex, RealmFieldType.DATE_LIST); osList.removeAll(); if (value == null) { return; diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index 8dc5f74452..2d9de383f7 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -933,7 +933,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldStringListNotNullRealmList != null) { return fieldStringListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldStringListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldStringListNotNullIndex, RealmFieldType.STRING_LIST); fieldStringListNotNullRealmList = new RealmList(java.lang.String.class, osList, proxyState.getRealm$realm()); return fieldStringListNotNullRealmList; } @@ -951,7 +951,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldStringListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldStringListNotNullIndex, RealmFieldType.STRING_LIST); osList.removeAll(); if (value == null) { return; @@ -972,7 +972,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldStringListNullRealmList != null) { return fieldStringListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldStringListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldStringListNullIndex, RealmFieldType.STRING_LIST); fieldStringListNullRealmList = new RealmList(java.lang.String.class, osList, proxyState.getRealm$realm()); return fieldStringListNullRealmList; } @@ -990,7 +990,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldStringListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldStringListNullIndex, RealmFieldType.STRING_LIST); osList.removeAll(); if (value == null) { return; @@ -1011,7 +1011,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldBinaryListNotNullRealmList != null) { return fieldBinaryListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBinaryListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldBinaryListNotNullIndex, RealmFieldType.BINARY_LIST); fieldBinaryListNotNullRealmList = new RealmList(byte[].class, osList, proxyState.getRealm$realm()); return fieldBinaryListNotNullRealmList; } @@ -1029,7 +1029,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBinaryListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldBinaryListNotNullIndex, RealmFieldType.BINARY_LIST); osList.removeAll(); if (value == null) { return; @@ -1050,7 +1050,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldBinaryListNullRealmList != null) { return fieldBinaryListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBinaryListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldBinaryListNullIndex, RealmFieldType.BINARY_LIST); fieldBinaryListNullRealmList = new RealmList(byte[].class, osList, proxyState.getRealm$realm()); return fieldBinaryListNullRealmList; } @@ -1068,7 +1068,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBinaryListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldBinaryListNullIndex, RealmFieldType.BINARY_LIST); osList.removeAll(); if (value == null) { return; @@ -1089,7 +1089,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldBooleanListNotNullRealmList != null) { return fieldBooleanListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBooleanListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldBooleanListNotNullIndex, RealmFieldType.BOOLEAN_LIST); fieldBooleanListNotNullRealmList = new RealmList(java.lang.Boolean.class, osList, proxyState.getRealm$realm()); return fieldBooleanListNotNullRealmList; } @@ -1107,7 +1107,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBooleanListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldBooleanListNotNullIndex, RealmFieldType.BOOLEAN_LIST); osList.removeAll(); if (value == null) { return; @@ -1128,7 +1128,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldBooleanListNullRealmList != null) { return fieldBooleanListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBooleanListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldBooleanListNullIndex, RealmFieldType.BOOLEAN_LIST); fieldBooleanListNullRealmList = new RealmList(java.lang.Boolean.class, osList, proxyState.getRealm$realm()); return fieldBooleanListNullRealmList; } @@ -1146,7 +1146,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldBooleanListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldBooleanListNullIndex, RealmFieldType.BOOLEAN_LIST); osList.removeAll(); if (value == null) { return; @@ -1167,7 +1167,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldLongListNotNullRealmList != null) { return fieldLongListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldLongListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldLongListNotNullIndex, RealmFieldType.INTEGER_LIST); fieldLongListNotNullRealmList = new RealmList(java.lang.Long.class, osList, proxyState.getRealm$realm()); return fieldLongListNotNullRealmList; } @@ -1185,7 +1185,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldLongListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldLongListNotNullIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -1206,7 +1206,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldLongListNullRealmList != null) { return fieldLongListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldLongListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldLongListNullIndex, RealmFieldType.INTEGER_LIST); fieldLongListNullRealmList = new RealmList(java.lang.Long.class, osList, proxyState.getRealm$realm()); return fieldLongListNullRealmList; } @@ -1224,7 +1224,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldLongListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldLongListNullIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -1245,7 +1245,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldIntegerListNotNullRealmList != null) { return fieldIntegerListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldIntegerListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldIntegerListNotNullIndex, RealmFieldType.INTEGER_LIST); fieldIntegerListNotNullRealmList = new RealmList(java.lang.Integer.class, osList, proxyState.getRealm$realm()); return fieldIntegerListNotNullRealmList; } @@ -1263,7 +1263,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldIntegerListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldIntegerListNotNullIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -1284,7 +1284,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldIntegerListNullRealmList != null) { return fieldIntegerListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldIntegerListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldIntegerListNullIndex, RealmFieldType.INTEGER_LIST); fieldIntegerListNullRealmList = new RealmList(java.lang.Integer.class, osList, proxyState.getRealm$realm()); return fieldIntegerListNullRealmList; } @@ -1302,7 +1302,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldIntegerListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldIntegerListNullIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -1323,7 +1323,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldShortListNotNullRealmList != null) { return fieldShortListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldShortListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldShortListNotNullIndex, RealmFieldType.INTEGER_LIST); fieldShortListNotNullRealmList = new RealmList(java.lang.Short.class, osList, proxyState.getRealm$realm()); return fieldShortListNotNullRealmList; } @@ -1341,7 +1341,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldShortListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldShortListNotNullIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -1362,7 +1362,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldShortListNullRealmList != null) { return fieldShortListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldShortListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldShortListNullIndex, RealmFieldType.INTEGER_LIST); fieldShortListNullRealmList = new RealmList(java.lang.Short.class, osList, proxyState.getRealm$realm()); return fieldShortListNullRealmList; } @@ -1380,7 +1380,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldShortListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldShortListNullIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -1401,7 +1401,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldByteListNotNullRealmList != null) { return fieldByteListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldByteListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldByteListNotNullIndex, RealmFieldType.INTEGER_LIST); fieldByteListNotNullRealmList = new RealmList(java.lang.Byte.class, osList, proxyState.getRealm$realm()); return fieldByteListNotNullRealmList; } @@ -1419,7 +1419,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldByteListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldByteListNotNullIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -1440,7 +1440,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldByteListNullRealmList != null) { return fieldByteListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldByteListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldByteListNullIndex, RealmFieldType.INTEGER_LIST); fieldByteListNullRealmList = new RealmList(java.lang.Byte.class, osList, proxyState.getRealm$realm()); return fieldByteListNullRealmList; } @@ -1458,7 +1458,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldByteListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldByteListNullIndex, RealmFieldType.INTEGER_LIST); osList.removeAll(); if (value == null) { return; @@ -1479,7 +1479,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldDoubleListNotNullRealmList != null) { return fieldDoubleListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDoubleListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldDoubleListNotNullIndex, RealmFieldType.DOUBLE_LIST); fieldDoubleListNotNullRealmList = new RealmList(java.lang.Double.class, osList, proxyState.getRealm$realm()); return fieldDoubleListNotNullRealmList; } @@ -1497,7 +1497,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDoubleListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldDoubleListNotNullIndex, RealmFieldType.DOUBLE_LIST); osList.removeAll(); if (value == null) { return; @@ -1518,7 +1518,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldDoubleListNullRealmList != null) { return fieldDoubleListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDoubleListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldDoubleListNullIndex, RealmFieldType.DOUBLE_LIST); fieldDoubleListNullRealmList = new RealmList(java.lang.Double.class, osList, proxyState.getRealm$realm()); return fieldDoubleListNullRealmList; } @@ -1536,7 +1536,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDoubleListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldDoubleListNullIndex, RealmFieldType.DOUBLE_LIST); osList.removeAll(); if (value == null) { return; @@ -1557,7 +1557,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldFloatListNotNullRealmList != null) { return fieldFloatListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldFloatListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldFloatListNotNullIndex, RealmFieldType.FLOAT_LIST); fieldFloatListNotNullRealmList = new RealmList(java.lang.Float.class, osList, proxyState.getRealm$realm()); return fieldFloatListNotNullRealmList; } @@ -1575,7 +1575,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldFloatListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldFloatListNotNullIndex, RealmFieldType.FLOAT_LIST); osList.removeAll(); if (value == null) { return; @@ -1596,7 +1596,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldFloatListNullRealmList != null) { return fieldFloatListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldFloatListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldFloatListNullIndex, RealmFieldType.FLOAT_LIST); fieldFloatListNullRealmList = new RealmList(java.lang.Float.class, osList, proxyState.getRealm$realm()); return fieldFloatListNullRealmList; } @@ -1614,7 +1614,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldFloatListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldFloatListNullIndex, RealmFieldType.FLOAT_LIST); osList.removeAll(); if (value == null) { return; @@ -1635,7 +1635,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldDateListNotNullRealmList != null) { return fieldDateListNotNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDateListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldDateListNotNullIndex, RealmFieldType.DATE_LIST); fieldDateListNotNullRealmList = new RealmList(java.util.Date.class, osList, proxyState.getRealm$realm()); return fieldDateListNotNullRealmList; } @@ -1653,7 +1653,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDateListNotNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldDateListNotNullIndex, RealmFieldType.DATE_LIST); osList.removeAll(); if (value == null) { return; @@ -1674,7 +1674,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { if (fieldDateListNullRealmList != null) { return fieldDateListNullRealmList; } else { - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDateListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldDateListNullIndex, RealmFieldType.DATE_LIST); fieldDateListNullRealmList = new RealmList(java.util.Date.class, osList, proxyState.getRealm$realm()); return fieldDateListNullRealmList; } @@ -1692,7 +1692,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } proxyState.getRealm$realm().checkIfValid(); - OsList osList = proxyState.getRow$realm().getList(columnInfo.fieldDateListNullIndex); + OsList osList = proxyState.getRow$realm().getValueList(columnInfo.fieldDateListNullIndex, RealmFieldType.DATE_LIST); osList.removeAll(); if (value == null) { return; diff --git a/realm/realm-library/src/main/java/io/realm/internal/CheckedRow.java b/realm/realm-library/src/main/java/io/realm/internal/CheckedRow.java index dd1b030c6e..f3a3e1f97b 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/CheckedRow.java +++ b/realm/realm-library/src/main/java/io/realm/internal/CheckedRow.java @@ -100,7 +100,6 @@ public void setNull(long columnIndex) { @Override public OsList getList(long columnIndex) { RealmFieldType fieldType = getTable().getColumnType(columnIndex); - // FIXME: Check types for primitive List. if (fieldType != RealmFieldType.LIST) { throw new IllegalArgumentException( String.format(Locale.US, "Field '%s' is not a 'RealmList'.", @@ -109,6 +108,28 @@ public OsList getList(long columnIndex) { return super.getList(columnIndex); } + @Override + public OsList getModelList(long columnIndex) { + RealmFieldType fieldType = getTable().getColumnType(columnIndex); + if (fieldType != RealmFieldType.LIST) { + throw new IllegalArgumentException( + String.format(Locale.US, "Field '%s' is not a 'RealmList'.", + getTable().getColumnName(columnIndex))); + } + return super.getModelList(columnIndex); + } + + @Override + public OsList getValueList(long columnIndex, RealmFieldType fieldType) { + final RealmFieldType actualFieldType = getTable().getColumnType(columnIndex); + if (fieldType != actualFieldType) { + throw new IllegalArgumentException( + String.format(Locale.US, "The type of field '%1$s' is not 'RealmFieldType.%2$s'.", + getTable().getColumnName(columnIndex), fieldType.name())); + } + return super.getValueList(columnIndex, fieldType); + } + @Override protected native long nativeGetColumnCount(long nativeTablePtr); diff --git a/realm/realm-library/src/main/java/io/realm/internal/InvalidRow.java b/realm/realm-library/src/main/java/io/realm/internal/InvalidRow.java index e3908cfb67..79510c7e08 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/InvalidRow.java +++ b/realm/realm-library/src/main/java/io/realm/internal/InvalidRow.java @@ -109,6 +109,16 @@ public OsList getList(long columnIndex) { throw getStubException(); } + @Override + public OsList getModelList(long columnIndex) { + throw getStubException(); + } + + @Override + public OsList getValueList(long columnIndex, RealmFieldType fieldType) { + throw getStubException(); + } + @Override public void setLong(long columnIndex, long value) { throw getStubException(); diff --git a/realm/realm-library/src/main/java/io/realm/internal/PendingRow.java b/realm/realm-library/src/main/java/io/realm/internal/PendingRow.java index f72b8e2a70..88ace3a27b 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/PendingRow.java +++ b/realm/realm-library/src/main/java/io/realm/internal/PendingRow.java @@ -138,6 +138,16 @@ public OsList getList(long columnIndex) { throw new IllegalStateException(QUERY_NOT_RETURNED_MESSAGE); } + @Override + public OsList getModelList(long columnIndex) { + throw new IllegalStateException(QUERY_NOT_RETURNED_MESSAGE); + } + + @Override + public OsList getValueList(long columnIndex, RealmFieldType fieldType) { + throw new IllegalStateException(QUERY_NOT_RETURNED_MESSAGE); + } + @Override public void setLong(long columnIndex, long value) { throw new IllegalStateException(QUERY_NOT_RETURNED_MESSAGE); diff --git a/realm/realm-library/src/main/java/io/realm/internal/Row.java b/realm/realm-library/src/main/java/io/realm/internal/Row.java index 49331c3a27..f1a556f057 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/Row.java +++ b/realm/realm-library/src/main/java/io/realm/internal/Row.java @@ -81,8 +81,13 @@ public interface Row { boolean isNullLink(long columnIndex); + // FIXME remove this in DynamicRealm PR OsList getList(long columnIndex); + OsList getModelList(long columnIndex); + + OsList getValueList(long columnIndex, RealmFieldType fieldType); + void setLong(long columnIndex, long value); void setBoolean(long columnIndex, boolean value); diff --git a/realm/realm-library/src/main/java/io/realm/internal/UncheckedRow.java b/realm/realm-library/src/main/java/io/realm/internal/UncheckedRow.java index aa60fb9f12..fbd7418aaf 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/UncheckedRow.java +++ b/realm/realm-library/src/main/java/io/realm/internal/UncheckedRow.java @@ -177,6 +177,16 @@ public OsList getList(long columnIndex) { return new OsList(this, columnIndex); } + @Override + public OsList getModelList(long columnIndex) { + return new OsList(this, columnIndex); + } + + @Override + public OsList getValueList(long columnIndex, RealmFieldType fieldType) { + return new OsList(this, columnIndex); + } + // Setters @Override From d4ee982a1c2e1cd4872e5d933184d2f68bc18add Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 13:15:06 +0300 Subject: [PATCH 37/72] update test case to expose an issue --- .../java/io/realm/ManagedRealmListForValueTests.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index c56a07df81..a2492a3537 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -427,9 +427,15 @@ public void execute(Realm realm) { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { + final long sizeBeforeException = list.size(); thrown.expect(IllegalArgumentException.class); - //noinspection unchecked - list.add(generateHugeValue(listType, sizeLimit + 1)); + try { + //noinspection unchecked + list.add(generateHugeValue(listType, sizeLimit + 1)); + } finally { + // FIXME This assertion fails now. Code will be fixed in master branch first. + assertEquals(sizeBeforeException, list.size()); + } } }); } From b22c309cd12a6e6e092548355d5f4ec8b2f7fdc1 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 14:42:18 +0300 Subject: [PATCH 38/72] address review feedback --- .../io/realm/processor/ClassMetaData.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java index 94a56f7369..4bdeff8f68 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java @@ -184,7 +184,7 @@ public boolean isNullable(VariableElement variableElement) { } /** - * Checks if the element of RealmList designated by {@code realmListVariableElement} is nullable. + * Checks if the element of {@code RealmList} designated by {@code realmListVariableElement} is nullable. * * @return {@code true} if the element is nullable type, {@code false} otherwise. */ @@ -468,17 +468,15 @@ private boolean categorizeField(Element element) { nullableValueListFields.add(field); } } + } else if (isRequiredField(field)) { + categorizeRequiredField(element, field); } else { - if (isRequiredField(field)) { - categorizeRequiredField(element, field); - } else { - // The field doesn't have the @Required and @org.jetbrains.annotations.NotNull annotation. - // Without @Required annotation, boxed types/RealmObject/Date/String/bytes should be added to - // nullableFields. - // RealmList and Primitive types are NOT nullable always. @Required annotation is not supported. - if (!Utils.isPrimitiveType(field)) { - nullableFields.add(field); - } + // The field doesn't have the @Required and @org.jetbrains.annotations.NotNull annotation. + // Without @Required annotation, boxed types/RealmObject/Date/String/bytes should be added to + // nullableFields. + // RealmList and Primitive types are NOT nullable always. @Required annotation is not supported. + if (!Utils.isPrimitiveType(field)) { + nullableFields.add(field); } } From d9707d78074ce502ff55a9e2878fd097dbad5cce Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 14:49:33 +0300 Subject: [PATCH 39/72] add notice to Realm.*Json*() --- .../src/main/java/io/realm/Realm.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/realm/realm-library/src/main/java/io/realm/Realm.java b/realm/realm-library/src/main/java/io/realm/Realm.java index bd85dd7bb3..8495ade044 100644 --- a/realm/realm-library/src/main/java/io/realm/Realm.java +++ b/realm/realm-library/src/main/java/io/realm/Realm.java @@ -430,6 +430,9 @@ static Realm createInstance(SharedRealm sharedRealm) { * JSON properties with unknown properties will be ignored. If a {@link RealmObject} field is not present in the * JSON object the {@link RealmObject} field will be set to the default value for that type. * + *

+ * This method currently does not support value list field. + * * @param clazz type of Realm objects to create. * @param json an array where each JSONObject must map to the specified class. * @throws RealmException if mapping from JSON fails. @@ -459,6 +462,9 @@ public void createAllFromJson(Class clazz, JSONArray j * a new {@link RealmObject} is created and a field is not found in the JSON object, that field will be assigned the * default value for the field type. * + *

+ * This method currently does not support value list field. + * * @param clazz type of {@link io.realm.RealmObject} to create or update. It must have a primary key defined. * @param json array with object data. * @throws IllegalArgumentException if trying to update a class without a {@link io.realm.annotations.PrimaryKey}. @@ -488,6 +494,9 @@ public void createOrUpdateAllFromJson(Class clazz, JSO * JSON properties with unknown properties will be ignored. If a {@link RealmObject} field is not present in the * JSON object the {@link RealmObject} field will be set to the default value for that type. * + *

+ * This method currently does not support value list field. + * * @param clazz type of Realm objects to create. * @param json the JSON array as a String where each object can map to the specified class. * @throws RealmException if mapping from JSON fails. @@ -517,6 +526,9 @@ public void createAllFromJson(Class clazz, String json * If a new {@link RealmObject} is created and a field is not found in the JSON object, that field will be assigned * the default value for the field type. * + *

+ * This method currently does not support value list field. + * * @param clazz type of {@link io.realm.RealmObject} to create or update. It must have a primary key defined. * @param json string with an array of JSON objects. * @throws IllegalArgumentException if trying to update a class without a {@link io.realm.annotations.PrimaryKey}. @@ -550,6 +562,9 @@ public void createOrUpdateAllFromJson(Class clazz, Str *

* This API is only available in API level 11 or later. * + *

+ * This method currently does not support value list field. + * * @param clazz type of Realm objects created. * @param inputStream the JSON array as a InputStream. All objects in the array must be of the specified class. * @throws RealmException if mapping from JSON fails. @@ -586,6 +601,9 @@ public void createAllFromJson(Class clazz, InputStream *

* This API is only available in API level 11 or later. * + *

+ * This method currently does not support value list field. + * * @param clazz type of {@link io.realm.RealmObject} to create or update. It must have a primary key defined. * @param in the InputStream with a list of object data in JSON format. * @throws IllegalArgumentException if trying to update a class without a {@link io.realm.annotations.PrimaryKey}. @@ -626,6 +644,9 @@ public void createOrUpdateAllFromJson(Class clazz, Inp * properties with unknown properties will be ignored. If a {@link RealmObject} field is not present in the JSON * object the {@link RealmObject} field will be set to the default value for that type. * + *

+ * This method currently does not support value list field. + * * @param clazz type of Realm object to create. * @param json the JSONObject with object data. * @return created object or {@code null} if no JSON data was provided. @@ -655,6 +676,9 @@ public E createObjectFromJson(Class clazz, JSONObject * and a field is not found in the JSON object, that field will not be updated. If a new {@link RealmObject} is * created and a field is not found in the JSON object, that field will be assigned the default value for the field type. * + *

+ * This method currently does not support value list field. + * * @param clazz Type of {@link io.realm.RealmObject} to create or update. It must have a primary key defined. * @param json {@link org.json.JSONObject} with object data. * @return created or updated {@link io.realm.RealmObject}. @@ -683,6 +707,9 @@ public E createOrUpdateObjectFromJson(Class clazz, JSO * properties with unknown properties will be ignored. If a {@link RealmObject} field is not present in the JSON * object the {@link RealmObject} field will be set to the default value for that type. * + *

+ * This method currently does not support value list field. + * * @param clazz type of Realm object to create. * @param json the JSON string with object data. * @return created object or {@code null} if JSON string was empty or null. @@ -714,6 +741,9 @@ public E createObjectFromJson(Class clazz, String json * {@link RealmObject} is created and a field is not found in the JSON object, that field will be assigned the * default value for the field type. * + *

+ * This method currently does not support value list field. + * * @param clazz type of {@link io.realm.RealmObject} to create or update. It must have a primary key defined. * @param json string with object data in JSON format. * @return created or updated {@link io.realm.RealmObject}. @@ -748,6 +778,9 @@ public E createOrUpdateObjectFromJson(Class clazz, Str *

* This API is only available in API level 11 or later. * + *

+ * This method currently does not support value list field. + * * @param clazz type of Realm object to create. * @param inputStream the JSON object data as a InputStream. * @return created object or {@code null} if JSON string was empty or null. @@ -802,6 +835,9 @@ public E createObjectFromJson(Class clazz, InputStream *

* This API is only available in API level 11 or later. * + *

+ * This method currently does not support value list field. + * * @param clazz type of {@link io.realm.RealmObject} to create or update. It must have a primary key defined. * @param in the {@link InputStream} with object data in JSON format. * @return created or updated {@link io.realm.RealmObject}. From 77d68cf81d0f02b7f48bd4fd09c69985e5f7798b Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 14:50:37 +0300 Subject: [PATCH 40/72] simplify Proxy's createDetachedCopy() --- .../processor/RealmProxyClassGenerator.java | 12 +- .../io/realm/AllTypesRealmProxy.java | 110 ++------ .../io/realm/NullTypesRealmProxy.java | 258 ++++-------------- 3 files changed, 81 insertions(+), 299 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 243f166ea7..dbbf65cb2a 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -1655,16 +1655,8 @@ private void emitCreateDetachedCopyMethod(JavaWriter writer) throws IOException } else if (Utils.isRealmValueList(field)) { writer .emitEmptyLine() - .beginControlFlow("do") - .emitStatement("RealmList<%s> managed%sList = realmSource.%s()", - Utils.getGenericTypeQualifiedName(field), fieldName, getter) - .emitStatement("RealmList<%1$s> unmanaged%2$sList = new RealmList<%1$s>()", Utils.getGenericTypeQualifiedName(field), fieldName) - .emitStatement("unmanagedCopy.%s(unmanaged%sList)", setter, fieldName) - .emitStatement("int size = managed%sList.size()", fieldName) - .beginControlFlow("for (int i = 0; i < size; i++)") - .emitStatement("unmanaged%1$sList.add(managed%1$sList.get(i))", fieldName) - .endControlFlow() - .endControlFlow("while (false)"); + .emitStatement("unmanagedCopy.%1$s(new RealmList<%2$s>())", setter, Utils.getGenericTypeQualifiedName(field)) + .emitStatement("unmanagedCopy.%1$s().addAll(realmSource.%1$s())", getter); } else if (Utils.isMutableRealmInteger(field)) { // If the user initializes the unmanaged MutableRealmInteger to null, this will fail mysteriously. writer.emitStatement("unmanagedCopy.%s().set(realmSource.%s().get())", getter, getter); diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index 7afb2b950f..87193b8d6f 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -2109,105 +2109,35 @@ public static some.test.AllTypes createDetachedCopy(some.test.AllTypes realmObje } } - do { - RealmList managedcolumnStringListList = realmSource.realmGet$columnStringList(); - RealmList unmanagedcolumnStringListList = new RealmList(); - unmanagedCopy.realmSet$columnStringList(unmanagedcolumnStringListList); - int size = managedcolumnStringListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnStringListList.add(managedcolumnStringListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnStringList(new RealmList()); + unmanagedCopy.realmGet$columnStringList().addAll(realmSource.realmGet$columnStringList()); - do { - RealmList managedcolumnBinaryListList = realmSource.realmGet$columnBinaryList(); - RealmList unmanagedcolumnBinaryListList = new RealmList(); - unmanagedCopy.realmSet$columnBinaryList(unmanagedcolumnBinaryListList); - int size = managedcolumnBinaryListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnBinaryListList.add(managedcolumnBinaryListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnBinaryList(new RealmList()); + unmanagedCopy.realmGet$columnBinaryList().addAll(realmSource.realmGet$columnBinaryList()); - do { - RealmList managedcolumnBooleanListList = realmSource.realmGet$columnBooleanList(); - RealmList unmanagedcolumnBooleanListList = new RealmList(); - unmanagedCopy.realmSet$columnBooleanList(unmanagedcolumnBooleanListList); - int size = managedcolumnBooleanListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnBooleanListList.add(managedcolumnBooleanListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnBooleanList(new RealmList()); + unmanagedCopy.realmGet$columnBooleanList().addAll(realmSource.realmGet$columnBooleanList()); - do { - RealmList managedcolumnLongListList = realmSource.realmGet$columnLongList(); - RealmList unmanagedcolumnLongListList = new RealmList(); - unmanagedCopy.realmSet$columnLongList(unmanagedcolumnLongListList); - int size = managedcolumnLongListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnLongListList.add(managedcolumnLongListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnLongList(new RealmList()); + unmanagedCopy.realmGet$columnLongList().addAll(realmSource.realmGet$columnLongList()); - do { - RealmList managedcolumnIntegerListList = realmSource.realmGet$columnIntegerList(); - RealmList unmanagedcolumnIntegerListList = new RealmList(); - unmanagedCopy.realmSet$columnIntegerList(unmanagedcolumnIntegerListList); - int size = managedcolumnIntegerListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnIntegerListList.add(managedcolumnIntegerListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnIntegerList(new RealmList()); + unmanagedCopy.realmGet$columnIntegerList().addAll(realmSource.realmGet$columnIntegerList()); - do { - RealmList managedcolumnShortListList = realmSource.realmGet$columnShortList(); - RealmList unmanagedcolumnShortListList = new RealmList(); - unmanagedCopy.realmSet$columnShortList(unmanagedcolumnShortListList); - int size = managedcolumnShortListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnShortListList.add(managedcolumnShortListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnShortList(new RealmList()); + unmanagedCopy.realmGet$columnShortList().addAll(realmSource.realmGet$columnShortList()); - do { - RealmList managedcolumnByteListList = realmSource.realmGet$columnByteList(); - RealmList unmanagedcolumnByteListList = new RealmList(); - unmanagedCopy.realmSet$columnByteList(unmanagedcolumnByteListList); - int size = managedcolumnByteListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnByteListList.add(managedcolumnByteListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnByteList(new RealmList()); + unmanagedCopy.realmGet$columnByteList().addAll(realmSource.realmGet$columnByteList()); - do { - RealmList managedcolumnDoubleListList = realmSource.realmGet$columnDoubleList(); - RealmList unmanagedcolumnDoubleListList = new RealmList(); - unmanagedCopy.realmSet$columnDoubleList(unmanagedcolumnDoubleListList); - int size = managedcolumnDoubleListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnDoubleListList.add(managedcolumnDoubleListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnDoubleList(new RealmList()); + unmanagedCopy.realmGet$columnDoubleList().addAll(realmSource.realmGet$columnDoubleList()); - do { - RealmList managedcolumnFloatListList = realmSource.realmGet$columnFloatList(); - RealmList unmanagedcolumnFloatListList = new RealmList(); - unmanagedCopy.realmSet$columnFloatList(unmanagedcolumnFloatListList); - int size = managedcolumnFloatListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnFloatListList.add(managedcolumnFloatListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnFloatList(new RealmList()); + unmanagedCopy.realmGet$columnFloatList().addAll(realmSource.realmGet$columnFloatList()); - do { - RealmList managedcolumnDateListList = realmSource.realmGet$columnDateList(); - RealmList unmanagedcolumnDateListList = new RealmList(); - unmanagedCopy.realmSet$columnDateList(unmanagedcolumnDateListList); - int size = managedcolumnDateListList.size(); - for (int i = 0; i < size; i++) { - unmanagedcolumnDateListList.add(managedcolumnDateListList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$columnDateList(new RealmList()); + unmanagedCopy.realmGet$columnDateList().addAll(realmSource.realmGet$columnDateList()); return unmanagedObject; } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index 2d9de383f7..729ac04210 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -3867,205 +3867,65 @@ public static some.test.NullTypes createDetachedCopy(some.test.NullTypes realmOb // Deep copy of fieldObjectNull unmanagedCopy.realmSet$fieldObjectNull(NullTypesRealmProxy.createDetachedCopy(realmSource.realmGet$fieldObjectNull(), currentDepth + 1, maxDepth, cache)); - do { - RealmList managedfieldStringListNotNullList = realmSource.realmGet$fieldStringListNotNull(); - RealmList unmanagedfieldStringListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldStringListNotNull(unmanagedfieldStringListNotNullList); - int size = managedfieldStringListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldStringListNotNullList.add(managedfieldStringListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldStringListNullList = realmSource.realmGet$fieldStringListNull(); - RealmList unmanagedfieldStringListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldStringListNull(unmanagedfieldStringListNullList); - int size = managedfieldStringListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldStringListNullList.add(managedfieldStringListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldBinaryListNotNullList = realmSource.realmGet$fieldBinaryListNotNull(); - RealmList unmanagedfieldBinaryListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldBinaryListNotNull(unmanagedfieldBinaryListNotNullList); - int size = managedfieldBinaryListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldBinaryListNotNullList.add(managedfieldBinaryListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldBinaryListNullList = realmSource.realmGet$fieldBinaryListNull(); - RealmList unmanagedfieldBinaryListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldBinaryListNull(unmanagedfieldBinaryListNullList); - int size = managedfieldBinaryListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldBinaryListNullList.add(managedfieldBinaryListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldBooleanListNotNullList = realmSource.realmGet$fieldBooleanListNotNull(); - RealmList unmanagedfieldBooleanListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldBooleanListNotNull(unmanagedfieldBooleanListNotNullList); - int size = managedfieldBooleanListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldBooleanListNotNullList.add(managedfieldBooleanListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldBooleanListNullList = realmSource.realmGet$fieldBooleanListNull(); - RealmList unmanagedfieldBooleanListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldBooleanListNull(unmanagedfieldBooleanListNullList); - int size = managedfieldBooleanListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldBooleanListNullList.add(managedfieldBooleanListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldLongListNotNullList = realmSource.realmGet$fieldLongListNotNull(); - RealmList unmanagedfieldLongListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldLongListNotNull(unmanagedfieldLongListNotNullList); - int size = managedfieldLongListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldLongListNotNullList.add(managedfieldLongListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldLongListNullList = realmSource.realmGet$fieldLongListNull(); - RealmList unmanagedfieldLongListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldLongListNull(unmanagedfieldLongListNullList); - int size = managedfieldLongListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldLongListNullList.add(managedfieldLongListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldIntegerListNotNullList = realmSource.realmGet$fieldIntegerListNotNull(); - RealmList unmanagedfieldIntegerListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldIntegerListNotNull(unmanagedfieldIntegerListNotNullList); - int size = managedfieldIntegerListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldIntegerListNotNullList.add(managedfieldIntegerListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldIntegerListNullList = realmSource.realmGet$fieldIntegerListNull(); - RealmList unmanagedfieldIntegerListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldIntegerListNull(unmanagedfieldIntegerListNullList); - int size = managedfieldIntegerListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldIntegerListNullList.add(managedfieldIntegerListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldShortListNotNullList = realmSource.realmGet$fieldShortListNotNull(); - RealmList unmanagedfieldShortListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldShortListNotNull(unmanagedfieldShortListNotNullList); - int size = managedfieldShortListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldShortListNotNullList.add(managedfieldShortListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldShortListNullList = realmSource.realmGet$fieldShortListNull(); - RealmList unmanagedfieldShortListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldShortListNull(unmanagedfieldShortListNullList); - int size = managedfieldShortListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldShortListNullList.add(managedfieldShortListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldByteListNotNullList = realmSource.realmGet$fieldByteListNotNull(); - RealmList unmanagedfieldByteListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldByteListNotNull(unmanagedfieldByteListNotNullList); - int size = managedfieldByteListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldByteListNotNullList.add(managedfieldByteListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldByteListNullList = realmSource.realmGet$fieldByteListNull(); - RealmList unmanagedfieldByteListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldByteListNull(unmanagedfieldByteListNullList); - int size = managedfieldByteListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldByteListNullList.add(managedfieldByteListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldDoubleListNotNullList = realmSource.realmGet$fieldDoubleListNotNull(); - RealmList unmanagedfieldDoubleListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldDoubleListNotNull(unmanagedfieldDoubleListNotNullList); - int size = managedfieldDoubleListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldDoubleListNotNullList.add(managedfieldDoubleListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldDoubleListNullList = realmSource.realmGet$fieldDoubleListNull(); - RealmList unmanagedfieldDoubleListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldDoubleListNull(unmanagedfieldDoubleListNullList); - int size = managedfieldDoubleListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldDoubleListNullList.add(managedfieldDoubleListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldFloatListNotNullList = realmSource.realmGet$fieldFloatListNotNull(); - RealmList unmanagedfieldFloatListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldFloatListNotNull(unmanagedfieldFloatListNotNullList); - int size = managedfieldFloatListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldFloatListNotNullList.add(managedfieldFloatListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldFloatListNullList = realmSource.realmGet$fieldFloatListNull(); - RealmList unmanagedfieldFloatListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldFloatListNull(unmanagedfieldFloatListNullList); - int size = managedfieldFloatListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldFloatListNullList.add(managedfieldFloatListNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldDateListNotNullList = realmSource.realmGet$fieldDateListNotNull(); - RealmList unmanagedfieldDateListNotNullList = new RealmList(); - unmanagedCopy.realmSet$fieldDateListNotNull(unmanagedfieldDateListNotNullList); - int size = managedfieldDateListNotNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldDateListNotNullList.add(managedfieldDateListNotNullList.get(i)); - } - } while (false); - - do { - RealmList managedfieldDateListNullList = realmSource.realmGet$fieldDateListNull(); - RealmList unmanagedfieldDateListNullList = new RealmList(); - unmanagedCopy.realmSet$fieldDateListNull(unmanagedfieldDateListNullList); - int size = managedfieldDateListNullList.size(); - for (int i = 0; i < size; i++) { - unmanagedfieldDateListNullList.add(managedfieldDateListNullList.get(i)); - } - } while (false); + unmanagedCopy.realmSet$fieldStringListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldStringListNotNull().addAll(realmSource.realmGet$fieldStringListNotNull()); + + unmanagedCopy.realmSet$fieldStringListNull(new RealmList()); + unmanagedCopy.realmGet$fieldStringListNull().addAll(realmSource.realmGet$fieldStringListNull()); + + unmanagedCopy.realmSet$fieldBinaryListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldBinaryListNotNull().addAll(realmSource.realmGet$fieldBinaryListNotNull()); + + unmanagedCopy.realmSet$fieldBinaryListNull(new RealmList()); + unmanagedCopy.realmGet$fieldBinaryListNull().addAll(realmSource.realmGet$fieldBinaryListNull()); + + unmanagedCopy.realmSet$fieldBooleanListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldBooleanListNotNull().addAll(realmSource.realmGet$fieldBooleanListNotNull()); + + unmanagedCopy.realmSet$fieldBooleanListNull(new RealmList()); + unmanagedCopy.realmGet$fieldBooleanListNull().addAll(realmSource.realmGet$fieldBooleanListNull()); + + unmanagedCopy.realmSet$fieldLongListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldLongListNotNull().addAll(realmSource.realmGet$fieldLongListNotNull()); + + unmanagedCopy.realmSet$fieldLongListNull(new RealmList()); + unmanagedCopy.realmGet$fieldLongListNull().addAll(realmSource.realmGet$fieldLongListNull()); + + unmanagedCopy.realmSet$fieldIntegerListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldIntegerListNotNull().addAll(realmSource.realmGet$fieldIntegerListNotNull()); + + unmanagedCopy.realmSet$fieldIntegerListNull(new RealmList()); + unmanagedCopy.realmGet$fieldIntegerListNull().addAll(realmSource.realmGet$fieldIntegerListNull()); + + unmanagedCopy.realmSet$fieldShortListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldShortListNotNull().addAll(realmSource.realmGet$fieldShortListNotNull()); + + unmanagedCopy.realmSet$fieldShortListNull(new RealmList()); + unmanagedCopy.realmGet$fieldShortListNull().addAll(realmSource.realmGet$fieldShortListNull()); + + unmanagedCopy.realmSet$fieldByteListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldByteListNotNull().addAll(realmSource.realmGet$fieldByteListNotNull()); + + unmanagedCopy.realmSet$fieldByteListNull(new RealmList()); + unmanagedCopy.realmGet$fieldByteListNull().addAll(realmSource.realmGet$fieldByteListNull()); + + unmanagedCopy.realmSet$fieldDoubleListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldDoubleListNotNull().addAll(realmSource.realmGet$fieldDoubleListNotNull()); + + unmanagedCopy.realmSet$fieldDoubleListNull(new RealmList()); + unmanagedCopy.realmGet$fieldDoubleListNull().addAll(realmSource.realmGet$fieldDoubleListNull()); + + unmanagedCopy.realmSet$fieldFloatListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldFloatListNotNull().addAll(realmSource.realmGet$fieldFloatListNotNull()); + + unmanagedCopy.realmSet$fieldFloatListNull(new RealmList()); + unmanagedCopy.realmGet$fieldFloatListNull().addAll(realmSource.realmGet$fieldFloatListNull()); + + unmanagedCopy.realmSet$fieldDateListNotNull(new RealmList()); + unmanagedCopy.realmGet$fieldDateListNotNull().addAll(realmSource.realmGet$fieldDateListNotNull()); + + unmanagedCopy.realmSet$fieldDateListNull(new RealmList()); + unmanagedCopy.realmGet$fieldDateListNull().addAll(realmSource.realmGet$fieldDateListNull()); return unmanagedObject; } From a0fb56018bd2b323757ff4f59d61fa54ea88a7c7 Mon Sep 17 00:00:00 2001 From: Chen Mulong Date: Thu, 14 Sep 2017 17:45:58 +0800 Subject: [PATCH 41/72] Support listener on OsList - Reuse the logic for Collection(OsResults) to support adding listeners on OsList. - Use OsList to handle notifications of primitive list. - Keep the current logic for RealmModel list -- handle notifications with a OsResults which is created from the OsList. --- .../realm/ManagedRealmListForValueTests.java | 39 ++++--- .../main/cpp/io_realm_internal_Collection.cpp | 109 +++++------------- .../src/main/cpp/io_realm_internal_OsList.cpp | 103 +++++++++++------ .../cpp/observable_collection_wrapper.hpp | 105 +++++++++++++++++ .../OrderedRealmCollectionChangeListener.java | 4 +- .../src/main/java/io/realm/RealmList.java | 51 ++++++-- .../java/io/realm/internal/Collection.java | 64 +--------- .../realm/internal/ObservableCollection.java | 72 ++++++++++++ .../main/java/io/realm/internal/OsList.java | 48 +++++++- 9 files changed, 384 insertions(+), 211 deletions(-) create mode 100644 realm/realm-library/src/main/cpp/observable_collection_wrapper.hpp create mode 100644 realm/realm-library/src/main/java/io/realm/internal/ObservableCollection.java diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index c56a07df81..21c3fbdc51 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -18,7 +18,6 @@ import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -54,6 +53,7 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -1037,7 +1037,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { + assertNotNull(changes); assertEquals(1, changes.getInsertions().length); assertEquals(0, changes.getDeletions().length); assertEquals(0, changes.getChanges().length); @@ -1056,7 +1057,6 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch } @Test - @Ignore("unexpected fail. Unexpected insertion index.") @RunTestInLooperThread public void changeListener_forAddAt() { Realm realm = looperThread.getRealm(); @@ -1087,7 +1087,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { + assertNotNull(changes); assertEquals(1, changes.getInsertions().length); assertEquals(0, changes.getDeletions().length); assertEquals(0, changes.getChanges().length); @@ -1106,7 +1107,6 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch } @Test - @Ignore("unexpected fail. Listener never be called.") @RunTestInLooperThread public void changeListener_forSet() { Realm realm = looperThread.getRealm(); @@ -1137,7 +1137,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { + assertNotNull(changes); assertEquals(0, changes.getInsertions().length); assertEquals(0, changes.getDeletions().length); assertEquals(1, changes.getChanges().length); @@ -1156,7 +1157,6 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch } @Test - @Ignore("unexpected fail. Unexpected deletion index.") @RunTestInLooperThread public void changeListener_forRemoveAt() { Realm realm = looperThread.getRealm(); @@ -1187,7 +1187,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { + assertNotNull(changes); assertEquals(0, changes.getInsertions().length); assertEquals(1, changes.getDeletions().length); assertEquals(0, changes.getChanges().length); @@ -1206,7 +1207,6 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch } @Test - @Ignore("unexpected fail. Unexpected deletion index.") @RunTestInLooperThread public void changeListener_forRemoveObject() { Realm realm = looperThread.getRealm(); @@ -1220,7 +1220,7 @@ public void execute(Realm realm) { //noinspection unchecked list.add(generateValue(listType, 0)); //noinspection unchecked - list.add(generateValue(listType, 100)); + list.add(generateValue(listType, 101)); //noinspection unchecked list.add(generateValue(listType, 200)); } @@ -1237,7 +1237,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { assertEquals(1, changes.getInsertions().length); + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { + assertNotNull(changes); assertEquals(0, changes.getInsertions().length); assertEquals(1, changes.getDeletions().length); assertEquals(0, changes.getChanges().length); @@ -1248,7 +1249,7 @@ public void onChange(RealmList element) { realm.beginTransaction(); //noinspection unchecked - list.remove(generateValue(listType, 100)); + list.remove(generateValue(listType, 101)); realm.commitTransaction(); assertEquals(2, listenerCalledCount.get()); @@ -1286,7 +1287,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { + assertNotNull(changes); assertEquals(0, changes.getInsertions().length); assertEquals(listType == BOOLEAN_LIST ? 3 : 2, changes.getDeletions().length); assertEquals(0, changes.getChanges().length); @@ -1307,7 +1309,6 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch } @Test - @Ignore("unexpected fail. Unexpected deletion index.") @RunTestInLooperThread public void changeListener_forDeleteAt() { Realm realm = looperThread.getRealm(); @@ -1338,7 +1339,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { + assertNotNull(changes); assertEquals(0, changes.getInsertions().length); assertEquals(1, changes.getDeletions().length); assertEquals(0, changes.getChanges().length); @@ -1387,7 +1389,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { + assertNotNull(changes); assertEquals(0, changes.getInsertions().length); assertEquals(3, changes.getDeletions().length); assertEquals(0, changes.getChanges().length); @@ -1429,7 +1432,7 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { fail(); } }); @@ -1479,7 +1482,7 @@ public void onChange(RealmList element) { OrderedRealmCollectionChangeListener> listener2 = new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + public void onChange(RealmList collection, @Nullable OrderedCollectionChangeSet changes) { assertEquals(0, listenerCalledCount.getAndIncrement()); looperThread.testComplete(); } diff --git a/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp b/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp index 34731cedcf..e9b6330a90 100644 --- a/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp +++ b/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp @@ -14,49 +14,22 @@ * limitations under the License. */ -#include #include "io_realm_internal_Collection.h" #include #include #include +#include "java_class_global_def.hpp" #include "java_sort_descriptor.hpp" +#include "observable_collection_wrapper.hpp" #include "util.hpp" -#include "java_class_global_def.hpp" - -#include "jni_util/java_class.hpp" -#include "jni_util/java_global_weak_ref.hpp" -#include "jni_util/java_method.hpp" using namespace realm; using namespace realm::jni_util; using namespace realm::_impl; -// We need to control the life cycle of Results, weak ref of Java Collection object and the NotificationToken. -// Wrap all three together, so when the Java Collection object gets GCed, all three of them will be invalidated. -struct ResultsWrapper { - JavaGlobalWeakRef m_collection_weak_ref; - NotificationToken m_notification_token; - Results m_results; - - ResultsWrapper(Results& results) - : m_collection_weak_ref() - , m_notification_token() - , m_results(std::move(results)) - { - } - - ResultsWrapper(ResultsWrapper&&) = delete; - ResultsWrapper& operator=(ResultsWrapper&&) = delete; - - ResultsWrapper(ResultsWrapper const&) = delete; - ResultsWrapper& operator=(ResultsWrapper const&) = delete; - - ~ResultsWrapper() - { - } -}; +typedef ObservableCollectionWrapper ResultsWrapper; static void finalize_results(jlong ptr); @@ -104,7 +77,8 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeCreateResultsFro { TR_ENTER() try { - auto& list = *reinterpret_cast(list_ptr); + auto& list_wrapper = *reinterpret_cast*>(list_ptr); + auto& list = list_wrapper.collection(); auto shared_realm = *(reinterpret_cast(shared_realm_ptr)); Results results = j_sort_desc ? list.sort(JavaSortDescriptor(env, j_sort_desc).sort_descriptor()) : @@ -122,7 +96,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeCreateSnapshot(J TR_ENTER_PTR(native_ptr); try { auto wrapper = reinterpret_cast(native_ptr); - auto snapshot_results = wrapper->m_results.snapshot(); + auto snapshot_results = wrapper->collection().snapshot(); auto snapshot_wrapper = new ResultsWrapper(snapshot_results); return reinterpret_cast(snapshot_wrapper); } @@ -137,7 +111,7 @@ JNIEXPORT jboolean JNICALL Java_io_realm_internal_Collection_nativeContains(JNIE try { auto wrapper = reinterpret_cast(native_ptr); auto row = reinterpret_cast(native_row_ptr); - size_t index = wrapper->m_results.index_of(RowExpr(*row)); + size_t index = wrapper->collection().index_of(RowExpr(*row)); return to_jbool(index != not_found); } CATCH_STD(); @@ -150,7 +124,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeGetRow(JNIEnv* e TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - auto row = wrapper->m_results.get(static_cast(index)); + auto row = wrapper->collection().get(static_cast(index)); return reinterpret_cast(new Row(std::move(row))); } CATCH_STD() @@ -162,7 +136,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeFirstRow(JNIEnv* TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - auto optional_row = wrapper->m_results.first(); + auto optional_row = wrapper->collection().first(); if (optional_row) { return reinterpret_cast(new Row(std::move(optional_row.value()))); } @@ -176,7 +150,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeLastRow(JNIEnv* TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - auto optional_row = wrapper->m_results.last(); + auto optional_row = wrapper->collection().last(); if (optional_row) { return reinterpret_cast(new Row(std::move(optional_row.value()))); } @@ -190,7 +164,7 @@ JNIEXPORT void JNICALL Java_io_realm_internal_Collection_nativeClear(JNIEnv* env TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - wrapper->m_results.clear(); + wrapper->collection().clear(); } CATCH_STD() } @@ -200,7 +174,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeSize(JNIEnv* env TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - return static_cast(wrapper->m_results.size()); + return static_cast(wrapper->collection().size()); } CATCH_STD() return 0; @@ -217,13 +191,13 @@ JNIEXPORT jobject JNICALL Java_io_realm_internal_Collection_nativeAggregate(JNIE Optional value; switch (agg_func) { case io_realm_internal_Collection_AGGREGATE_FUNCTION_MINIMUM: - value = wrapper->m_results.min(index); + value = wrapper->collection().min(index); break; case io_realm_internal_Collection_AGGREGATE_FUNCTION_MAXIMUM: - value = wrapper->m_results.max(index); + value = wrapper->collection().max(index); break; case io_realm_internal_Collection_AGGREGATE_FUNCTION_AVERAGE: { - Optional value_count(wrapper->m_results.average(index)); + Optional value_count(wrapper->collection().average(index)); if (value_count) { value = Optional(Mixed(value_count.value())); } @@ -233,7 +207,7 @@ JNIEXPORT jobject JNICALL Java_io_realm_internal_Collection_nativeAggregate(JNIE break; } case io_realm_internal_Collection_AGGREGATE_FUNCTION_SUM: - value = wrapper->m_results.sum(index); + value = wrapper->collection().sum(index); break; default: REALM_UNREACHABLE(); @@ -267,7 +241,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeSort(JNIEnv* env TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - auto sorted_result = wrapper->m_results.sort(JavaSortDescriptor(env, j_sort_desc).sort_descriptor()); + auto sorted_result = wrapper->collection().sort(JavaSortDescriptor(env, j_sort_desc).sort_descriptor()); return reinterpret_cast(new ResultsWrapper(sorted_result)); } CATCH_STD() @@ -281,7 +255,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeDistinct(JNIEnv* try { auto wrapper = reinterpret_cast(native_ptr); auto distinct_result = - wrapper->m_results.distinct(JavaSortDescriptor(env, j_distinct_desc).distinct_descriptor()); + wrapper->collection().distinct(JavaSortDescriptor(env, j_distinct_desc).distinct_descriptor()); return reinterpret_cast(new ResultsWrapper(distinct_result)); } CATCH_STD() @@ -293,38 +267,9 @@ JNIEXPORT void JNICALL Java_io_realm_internal_Collection_nativeStartListening(JN { TR_ENTER_PTR(native_ptr) - static JavaClass os_results_class(env, "io/realm/internal/Collection"); - static JavaMethod notify_change_listeners(env, os_results_class, "notifyChangeListeners", "(J)V"); - try { auto wrapper = reinterpret_cast(native_ptr); - if (!wrapper->m_collection_weak_ref) { - wrapper->m_collection_weak_ref = JavaGlobalWeakRef(env, instance); - } - - auto cb = [=](CollectionChangeSet const& changes, std::exception_ptr err) { - // OS will call all notifiers' callback in one run, so check the Java exception first!! - if (env->ExceptionCheck()) - return; - - if (err) { - try { - std::rethrow_exception(err); - } - catch (const std::exception& e) { - realm::jni_util::Log::e("Caught exception in collection change callback %1", e.what()); - return; - } - } - - wrapper->m_collection_weak_ref.call_with_local_ref(env, [&](JNIEnv* local_env, jobject collection_obj) { - local_env->CallVoidMethod( - collection_obj, notify_change_listeners, - reinterpret_cast(changes.empty() ? 0 : new CollectionChangeSet(changes))); - }); - }; - - wrapper->m_notification_token = wrapper->m_results.add_notification_callback(cb); + wrapper->start_listening(env, instance); } CATCH_STD() } @@ -335,7 +280,7 @@ JNIEXPORT void JNICALL Java_io_realm_internal_Collection_nativeStopListening(JNI try { auto wrapper = reinterpret_cast(native_ptr); - wrapper->m_notification_token = {}; + wrapper->stop_listening(); } CATCH_STD() } @@ -352,7 +297,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeWhere(JNIEnv* en try { auto wrapper = reinterpret_cast(native_ptr); - auto table_view = wrapper->m_results.get_tableview(); + auto table_view = wrapper->collection().get_tableview(); Query* query = new Query(table_view.get_parent(), std::unique_ptr(new TableView(std::move(table_view)))); return reinterpret_cast(query); @@ -369,7 +314,7 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_Collection_nativeIndexOf(JNIEnv* auto wrapper = reinterpret_cast(native_ptr); auto row = reinterpret_cast(row_native_ptr); - return static_cast(wrapper->m_results.index_of(RowExpr(*row))); + return static_cast(wrapper->collection().index_of(RowExpr(*row))); } CATCH_STD() return npos; @@ -380,7 +325,7 @@ JNIEXPORT jboolean JNICALL Java_io_realm_internal_Collection_nativeDeleteLast(JN TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - auto row = wrapper->m_results.last(); + auto row = wrapper->collection().last(); if (row && row->is_attached()) { row->move_last_over(); return JNI_TRUE; @@ -396,7 +341,7 @@ JNIEXPORT jboolean JNICALL Java_io_realm_internal_Collection_nativeDeleteFirst(J try { auto wrapper = reinterpret_cast(native_ptr); - auto row = wrapper->m_results.first(); + auto row = wrapper->collection().first(); if (row && row->is_attached()) { row->move_last_over(); return JNI_TRUE; @@ -413,7 +358,7 @@ JNIEXPORT void JNICALL Java_io_realm_internal_Collection_nativeDelete(JNIEnv* en try { auto wrapper = reinterpret_cast(native_ptr); - auto row = wrapper->m_results.get(index); + auto row = wrapper->collection().get(index); if (row.is_attached()) { row.move_last_over(); } @@ -426,7 +371,7 @@ JNIEXPORT jboolean JNICALL Java_io_realm_internal_Collection_nativeIsValid(JNIEn TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - return wrapper->m_results.is_valid(); + return wrapper->collection().is_valid(); } CATCH_STD() return JNI_FALSE; @@ -437,7 +382,7 @@ JNIEXPORT jbyte JNICALL Java_io_realm_internal_Collection_nativeGetMode(JNIEnv* TR_ENTER_PTR(native_ptr) try { auto wrapper = reinterpret_cast(native_ptr); - switch (wrapper->m_results.get_mode()) { + switch (wrapper->collection().get_mode()) { case Results::Mode::Empty: return io_realm_internal_Collection_MODE_EMPTY; case Results::Mode::Table: diff --git a/realm/realm-library/src/main/cpp/io_realm_internal_OsList.cpp b/realm/realm-library/src/main/cpp/io_realm_internal_OsList.cpp index 53c1804b7a..ccee1c9720 100644 --- a/realm/realm-library/src/main/cpp/io_realm_internal_OsList.cpp +++ b/realm/realm-library/src/main/cpp/io_realm_internal_OsList.cpp @@ -20,6 +20,7 @@ #include #include +#include "observable_collection_wrapper.hpp" #include "java_accessor.hpp" #include "java_exception_def.hpp" #include "jni_util/java_exception_thrower.hpp" @@ -29,42 +30,44 @@ using namespace realm; using namespace realm::util; using namespace realm::_impl; +typedef ObservableCollectionWrapper ListWrapper; + namespace { void finalize_list(jlong ptr) { TR_ENTER_PTR(ptr) - delete reinterpret_cast(ptr); + delete reinterpret_cast(ptr); } inline void add_value(JNIEnv* env, jlong list_ptr, Any&& value) { - auto& list = *reinterpret_cast(list_ptr); + auto& wrapper = *reinterpret_cast(list_ptr); JavaAccessorContext context(env); - list.add(context, value); + wrapper.collection().add(context, value); } inline void insert_value(JNIEnv* env, jlong list_ptr, jlong pos, Any&& value) { - auto& list = *reinterpret_cast(list_ptr); + auto& wrapper = *reinterpret_cast(list_ptr); JavaAccessorContext context(env); - list.insert(context, pos, value); + wrapper.collection().insert(context, pos, value); } inline void set_value(JNIEnv* env, jlong list_ptr, jlong pos, Any&& value) { - auto& list = *reinterpret_cast(list_ptr); + auto& wrapper = *reinterpret_cast(list_ptr); JavaAccessorContext context(env); - list.set(context, pos, value); + wrapper.collection().set(context, pos, value); } // Check nullable earlier https://github.com/realm/realm-object-store/issues/544 inline void check_nullable(JNIEnv* env, jlong list_ptr, jobject jobject_ptr = nullptr) { - auto& list = *reinterpret_cast(list_ptr); - if (!jobject_ptr && !is_nullable(list.get_type())) { + auto& wrapper = *reinterpret_cast(list_ptr); + if (!jobject_ptr && !is_nullable(wrapper.collection().get_type())) { THROW_JAVA_EXCEPTION(env, JavaExceptionDef::IllegalArgument, "This 'RealmList' is not nullable. A non-null value is expected."); } @@ -92,10 +95,11 @@ JNIEXPORT jlongArray JNICALL Java_io_realm_internal_OsList_nativeCreate(JNIEnv* auto& shared_realm = *reinterpret_cast(shared_realm_ptr); jlong ret[2]; - auto list_ptr = new List(shared_realm, *row.get_table(), column_index, row.get_index()); - ret[0] = reinterpret_cast(list_ptr); + List list(shared_realm, *row.get_table(), column_index, row.get_index()); + ListWrapper* wrapper_ptr = new ListWrapper(list); + ret[0] = reinterpret_cast(wrapper_ptr); - if (list_ptr->get_type() == PropertyType::Object) { + if (wrapper_ptr->collection().get_type() == PropertyType::Object) { LinkViewRef link_view_ref(row.get_linklist(column_index)); Table* target_table_ptr = &(link_view_ref)->get_target_table(); @@ -124,8 +128,8 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_OsList_nativeGetRow(JNIEnv* env, TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - auto row = list.get(column_index); + auto& wrapper = *reinterpret_cast(list_ptr); + auto row = wrapper.collection().get(column_index); return reinterpret_cast(new Row(std::move(row))); } CATCH_STD() @@ -138,8 +142,8 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeAddRow(JNIEnv* env, j TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - list.add(static_cast(target_row_index)); + auto& wrapper = *reinterpret_cast(list_ptr); + wrapper.collection().add(static_cast(target_row_index)); } CATCH_STD() } @@ -150,8 +154,8 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeInsertRow(JNIEnv* env TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - list.insert(static_cast(pos), static_cast(target_row_index)); + auto& wrapper = *reinterpret_cast(list_ptr); + wrapper.collection().insert(static_cast(pos), static_cast(target_row_index)); } CATCH_STD() } @@ -162,8 +166,8 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeSetRow(JNIEnv* env, j TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - list.set(static_cast(pos), static_cast(target_row_index)); + auto& wrapper = *reinterpret_cast(list_ptr); + wrapper.collection().set(static_cast(pos), static_cast(target_row_index)); } CATCH_STD() } @@ -174,8 +178,8 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeMove(JNIEnv* env, jcl TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - list.move(source_index, target_index); + auto& wrapper = *reinterpret_cast(list_ptr); + wrapper.collection().move(source_index, target_index); } CATCH_STD() } @@ -185,8 +189,8 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeRemove(JNIEnv* env, j TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - list.remove(index); + auto& wrapper = *reinterpret_cast(list_ptr); + wrapper.collection().remove(index); } CATCH_STD() } @@ -196,8 +200,8 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeRemoveAll(JNIEnv* env TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - list.remove_all(); + auto& wrapper = *reinterpret_cast(list_ptr); + wrapper.collection().remove_all(); } CATCH_STD() } @@ -207,8 +211,8 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_OsList_nativeSize(JNIEnv* env, jc TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - return list.size(); + auto& wrapper = *reinterpret_cast(list_ptr); + return wrapper.collection().size(); } CATCH_STD() return 0; @@ -219,8 +223,8 @@ JNIEXPORT jlong JNICALL Java_io_realm_internal_OsList_nativeGetQuery(JNIEnv* env TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - auto query = list.get_query(); + auto& wrapper = *reinterpret_cast(list_ptr); + auto query = wrapper.collection().get_query(); return reinterpret_cast(new Query(std::move(query))); } CATCH_STD() @@ -232,8 +236,8 @@ JNIEXPORT jboolean JNICALL Java_io_realm_internal_OsList_nativeIsValid(JNIEnv* e TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - return list.is_valid(); + auto& wrapper = *reinterpret_cast(list_ptr); + return wrapper.collection().is_valid(); } CATCH_STD() return JNI_FALSE; @@ -244,8 +248,8 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeDelete(JNIEnv* env, j TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - list.delete_at(S(index)); + auto& wrapper = *reinterpret_cast(list_ptr); + wrapper.collection().delete_at(S(index)); } CATCH_STD() } @@ -255,8 +259,31 @@ JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeDeleteAll(JNIEnv* env TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); - list.delete_all(); + auto& wrapper = *reinterpret_cast(list_ptr); + wrapper.collection().delete_all(); + } + CATCH_STD() +} + +JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeStartListening(JNIEnv* env, jobject instance, + jlong native_ptr) +{ + TR_ENTER_PTR(native_ptr) + + try { + auto wrapper = reinterpret_cast(native_ptr); + wrapper->start_listening(env, instance); + } + CATCH_STD() +} + +JNIEXPORT void JNICALL Java_io_realm_internal_OsList_nativeStopListening(JNIEnv* env, jobject, jlong native_ptr) +{ + TR_ENTER_PTR(native_ptr) + + try { + auto wrapper = reinterpret_cast(native_ptr); + wrapper->stop_listening(); } CATCH_STD() } @@ -514,9 +541,9 @@ JNIEXPORT jobject JNICALL Java_io_realm_internal_OsList_nativeGetValue(JNIEnv* e { TR_ENTER_PTR(list_ptr) try { - auto& list = *reinterpret_cast(list_ptr); + auto& wrapper = *reinterpret_cast(list_ptr); JavaAccessorContext context(env); - return any_cast(list.get(context, pos)); + return any_cast(wrapper.collection().get(context, pos)); } CATCH_STD() diff --git a/realm/realm-library/src/main/cpp/observable_collection_wrapper.hpp b/realm/realm-library/src/main/cpp/observable_collection_wrapper.hpp new file mode 100644 index 0000000000..ed53c62c9f --- /dev/null +++ b/realm/realm-library/src/main/cpp/observable_collection_wrapper.hpp @@ -0,0 +1,105 @@ +/* + * Copyright 2017 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef REALM_JNI_IMPL_OBSERVABLE_COLLECTION_WRAPPER_HPP +#define REALM_JNI_IMPL_OBSERVABLE_COLLECTION_WRAPPER_HPP + +#include "jni_util/java_class.hpp" +#include "jni_util/java_global_weak_ref.hpp" +#include "jni_util/java_method.hpp" +#include "jni_util/log.hpp" + +namespace realm { +namespace _impl { + +// Wrapper of Object Store List & Results. +// We need to control the life cycle of Results/List, weak ref of Java Collection object and the NotificationToken. +// Wrap all three together, so when the Java Collection object gets GCed, all three of them will be invalidated. +template +class ObservableCollectionWrapper { +public: + ObservableCollectionWrapper(T& collection) + : m_collection_weak_ref() + , m_notification_token() + , m_collection(std::move(collection)) + { + } + + ~ObservableCollectionWrapper() = default; + + ObservableCollectionWrapper(ObservableCollectionWrapper&&) = delete; + ObservableCollectionWrapper& operator=(ObservableCollectionWrapper&&) = delete; + ObservableCollectionWrapper(ObservableCollectionWrapper const&) = delete; + ObservableCollectionWrapper& operator=(ObservableCollectionWrapper const&) = delete; + + T& collection() + { + return m_collection; + }; + void start_listening(JNIEnv* env, jobject j_collection_object); + void stop_listening(); + +private: + jni_util::JavaGlobalWeakRef m_collection_weak_ref; + NotificationToken m_notification_token; + T m_collection; +}; + +template +void ObservableCollectionWrapper::start_listening(JNIEnv* env, jobject j_collection_object) +{ + static jni_util::JavaClass os_results_class(env, "io/realm/internal/ObservableCollection"); + static jni_util::JavaMethod notify_change_listeners(env, os_results_class, "notifyChangeListeners", "(J)V"); + + if (!m_collection_weak_ref) { + m_collection_weak_ref = jni_util::JavaGlobalWeakRef(env, j_collection_object); + } + + auto cb = [=](CollectionChangeSet const& changes, std::exception_ptr err) { + // OS will call all notifiers' callback in one run, so check the Java exception first!! + if (env->ExceptionCheck()) + return; + + if (err) { + try { + std::rethrow_exception(err); + } + catch (const std::exception& e) { + realm::jni_util::Log::e("Caught exception in collection change callback %1", e.what()); + return; + } + } + + m_collection_weak_ref.call_with_local_ref(env, [&](JNIEnv* local_env, jobject collection_obj) { + local_env->CallVoidMethod( + collection_obj, notify_change_listeners, + reinterpret_cast(changes.empty() ? 0 : new CollectionChangeSet(changes))); + }); + }; + + m_notification_token = m_collection.add_notification_callback(cb); +} + +template +void ObservableCollectionWrapper::stop_listening() +{ + m_notification_token = {}; +} + +} // namespace realm +} // namespace _impl + +#endif // REALM_JNI_IMPL_OBSERVABLE_COLLECTION_WRAPPER_HPP diff --git a/realm/realm-library/src/main/java/io/realm/OrderedRealmCollectionChangeListener.java b/realm/realm-library/src/main/java/io/realm/OrderedRealmCollectionChangeListener.java index b9a5261c85..24216e776d 100644 --- a/realm/realm-library/src/main/java/io/realm/OrderedRealmCollectionChangeListener.java +++ b/realm/realm-library/src/main/java/io/realm/OrderedRealmCollectionChangeListener.java @@ -16,6 +16,8 @@ package io.realm; +import javax.annotation.Nullable; + /** * {@link OrderedRealmCollectionChangeListener} can be registered with a {@link RealmResults} to receive a notification * with a {@link OrderedCollectionChangeSet} to describe the details of what have been changed in the collection from @@ -36,5 +38,5 @@ public interface OrderedRealmCollectionChangeListener { * @param changeSet object with information about which rows in the collection were added, removed or modified. * {@code null} is returned the first time an async query is completed. */ - void onChange(T t, OrderedCollectionChangeSet changeSet); + void onChange(T t, @Nullable OrderedCollectionChangeSet changeSet); } diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 0bdafd4c52..27f52236d1 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -64,7 +64,6 @@ public class RealmList extends AbstractList implements OrderedRealmCollect private static final String ALLOWED_ONLY_FOR_REALM_MODEL_ELEMENT_MESSAGE = "This feature is available only when the element type is implementing RealmModel"; public static final String REMOVE_OUTSIDE_TRANSACTION_ERROR = "Objects can only be removed from inside a write transaction"; - private final io.realm.internal.Collection collection; @Nullable protected Class clazz; @Nullable @@ -74,6 +73,8 @@ public class RealmList extends AbstractList implements OrderedRealmCollect private final ManagedListOperator osListOperator; final protected BaseRealm realm; private List unmanagedList; + // Used for listeners on RealmList + private io.realm.internal.Collection osResults; /** * Creates a RealmList in unmanaged mode, where the elements are not controlled by a Realm. @@ -83,7 +84,6 @@ public class RealmList extends AbstractList implements OrderedRealmCollect * Use {@link io.realm.Realm#copyToRealm(Iterable)} to properly persist its elements in Realm. */ public RealmList() { - collection = null; realm = null; osListOperator = null; unmanagedList = new ArrayList<>(); @@ -104,7 +104,6 @@ public RealmList(E... objects) { if (objects == null) { throw new IllegalArgumentException("The objects argument cannot be null"); } - collection = null; realm = null; osListOperator = null; unmanagedList = new ArrayList<>(objects.length); @@ -119,14 +118,12 @@ public RealmList(E... objects) { * @param realm reference to Realm containing the data. */ RealmList(Class clazz, OsList osList, BaseRealm realm) { - this.collection = new io.realm.internal.Collection(realm.sharedRealm, osList, null); this.clazz = clazz; osListOperator = getOperator(realm, osList, clazz, null); this.realm = realm; } RealmList(String className, OsList osList, BaseRealm realm) { - this.collection = new io.realm.internal.Collection(realm.sharedRealm, osList, null); this.realm = realm; this.className = className; osListOperator = getOperator(realm, osList, null, className); @@ -1034,7 +1031,11 @@ private void checkForAddRemoveListener(@Nullable Object listener, boolean checkL */ public void addChangeListener(OrderedRealmCollectionChangeListener> listener) { checkForAddRemoveListener(listener, true); - collection.addListener(this, listener); + if (osListOperator.forRealmModel()) { + getOrCreateOsResultsForListener().addListener(this, listener); + } else { + osListOperator.getOsList().addListener(this, listener); + } } /** @@ -1047,7 +1048,11 @@ public void addChangeListener(OrderedRealmCollectionChangeListener> */ public void removeChangeListener(OrderedRealmCollectionChangeListener> listener) { checkForAddRemoveListener(listener, true); - collection.removeListener(this, listener); + if (osListOperator.forRealmModel()) { + getOrCreateOsResultsForListener().removeListener(this, listener); + } else { + osListOperator.getOsList().removeListener(this, listener); + } } /** @@ -1085,7 +1090,11 @@ public void removeChangeListener(OrderedRealmCollectionChangeListener> listener) { checkForAddRemoveListener(listener, true); - collection.addListener(this, listener); + if (osListOperator.forRealmModel()) { + getOrCreateOsResultsForListener().addListener(this, listener); + } else { + osListOperator.getOsList().addListener(this, listener); + } } /** @@ -1098,7 +1107,11 @@ public void addChangeListener(RealmChangeListener> listener) { */ public void removeChangeListener(RealmChangeListener> listener) { checkForAddRemoveListener(listener, true); - collection.removeListener(this, listener); + if (osListOperator.forRealmModel()) { + getOrCreateOsResultsForListener().removeListener(this, listener); + } else { + osListOperator.getOsList().removeListener(this, listener); + } } /** @@ -1109,7 +1122,11 @@ public void removeChangeListener(RealmChangeListener> listener) { */ public void removeAllChangeListeners() { checkForAddRemoveListener(null, false); - collection.removeAllListeners(); + if (osListOperator.forRealmModel()) { + getOrCreateOsResultsForListener().removeAllListeners(); + } else { + osListOperator.getOsList().removeAllListeners(); + } } // Custom RealmList iterator. @@ -1870,6 +1887,20 @@ private ManagedListOperator getOperator(BaseRealm realm, OsList osList, @Null } throw new IllegalArgumentException("Unexpected value class: " + clazz.getName()); } + + // TODO: Object Store is not able to merge change set for links list. Luckily since we were still using LinkView + // when ship the fine grain notifications, the listener on RealmList is actually added to a OS Results which is + // created from the link view. OS Results is computing the change set by comparing the old/new collection. So it + // will give the right results if you remove all elements from a RealmList then add all them back and add one more + // new element. By right results it means the change set only include one insertion. But if the listener is on the + // OS List, the change set will include all ranges of th list. So we keep the old behaviour for + // RealmList for now. See https://github.com/realm/realm-object-store/issues/541 + private io.realm.internal.Collection getOrCreateOsResultsForListener() { + if (osResults == null) { + this.osResults = new io.realm.internal.Collection(realm.sharedRealm, osListOperator.getOsList(), null); + } + return osResults; + } } abstract class ManagedListOperator { diff --git a/realm/realm-library/src/main/java/io/realm/internal/Collection.java b/realm/realm-library/src/main/java/io/realm/internal/Collection.java index d46e7b8538..df0b2c6cf0 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/Collection.java +++ b/realm/realm-library/src/main/java/io/realm/internal/Collection.java @@ -22,7 +22,6 @@ import javax.annotation.Nullable; -import io.realm.OrderedCollectionChangeSet; import io.realm.OrderedRealmCollectionChangeListener; import io.realm.RealmChangeListener; @@ -31,68 +30,11 @@ * Java wrapper of Object Store Results class. * It is the backend of binding's query results and back links. */ -@Keep -public class Collection implements NativeObject { +public class Collection implements NativeObject, ObservableCollection { private static final String CLOSED_REALM_MESSAGE = "This Realm instance has already been closed, making it unusable."; - private static class CollectionObserverPair extends ObserverPairList.ObserverPair { - public CollectionObserverPair(T observer, Object listener) { - super(observer, listener); - } - - public void onChange(T observer, OrderedCollectionChangeSet changes) { - if (listener instanceof OrderedRealmCollectionChangeListener) { - //noinspection unchecked - ((OrderedRealmCollectionChangeListener) listener).onChange(observer, changes); - } else if (listener instanceof RealmChangeListener) { - //noinspection unchecked - ((RealmChangeListener) listener).onChange(observer); - } else { - throw new RuntimeException("Unsupported listener type: " + listener); - } - } - } - - private static class RealmChangeListenerWrapper implements OrderedRealmCollectionChangeListener { - private final RealmChangeListener listener; - - RealmChangeListenerWrapper(RealmChangeListener listener) { - this.listener = listener; - } - - @Override - public void onChange(T collection, OrderedCollectionChangeSet changes) { - listener.onChange(collection); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof RealmChangeListenerWrapper && - listener == ((RealmChangeListenerWrapper) obj).listener; - } - - @Override - public int hashCode() { - return listener.hashCode(); - } - } - - private static class Callback implements ObserverPairList.Callback { - private final OrderedCollectionChangeSet changeSet; - - Callback(OrderedCollectionChangeSet changeSet) { - this.changeSet = changeSet; - } - - @Override - public void onCalled(CollectionObserverPair pair, Object observer) { - //noinspection unchecked - pair.onChange(observer, changeSet); - } - } - // Custom Collection iterator. It ensures that we only iterate on a Realm collection that hasn't changed. public static abstract class Iterator implements java.util.Iterator { Collection iteratorCollection; @@ -517,8 +459,8 @@ public boolean isValid() { } // Called by JNI - @SuppressWarnings("unused") - private void notifyChangeListeners(long nativeChangeSetPtr) { + @Override + public void notifyChangeListeners(long nativeChangeSetPtr) { if (nativeChangeSetPtr == 0 && isLoaded()) { return; } diff --git a/realm/realm-library/src/main/java/io/realm/internal/ObservableCollection.java b/realm/realm-library/src/main/java/io/realm/internal/ObservableCollection.java new file mode 100644 index 0000000000..7004df192c --- /dev/null +++ b/realm/realm-library/src/main/java/io/realm/internal/ObservableCollection.java @@ -0,0 +1,72 @@ +package io.realm.internal; + +import javax.annotation.Nullable; + +import io.realm.OrderedCollectionChangeSet; +import io.realm.OrderedRealmCollectionChangeListener; +import io.realm.RealmChangeListener; + +// Helper class for supporting add change listeners on OsResults & OsList. +@Keep +interface ObservableCollection { + + class CollectionObserverPair extends ObserverPairList.ObserverPair { + public CollectionObserverPair(T observer, Object listener) { + super(observer, listener); + } + + public void onChange(T observer, @Nullable OrderedCollectionChangeSet changes) { + if (listener instanceof OrderedRealmCollectionChangeListener) { + //noinspection unchecked + ((OrderedRealmCollectionChangeListener) listener).onChange(observer, changes); + } else if (listener instanceof RealmChangeListener) { + //noinspection unchecked + ((RealmChangeListener) listener).onChange(observer); + } else { + throw new RuntimeException("Unsupported listener type: " + listener); + } + } + } + + class RealmChangeListenerWrapper implements OrderedRealmCollectionChangeListener { + private final RealmChangeListener listener; + + RealmChangeListenerWrapper(RealmChangeListener listener) { + this.listener = listener; + } + + @Override + public void onChange(T collection, @Nullable OrderedCollectionChangeSet changes) { + listener.onChange(collection); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof RealmChangeListenerWrapper && + listener == ((RealmChangeListenerWrapper) obj).listener; + } + + @Override + public int hashCode() { + return listener.hashCode(); + } + } + + class Callback implements ObserverPairList.Callback { + private final OrderedCollectionChangeSet changeSet; + + Callback(@Nullable OrderedCollectionChangeSet changeSet) { + this.changeSet = changeSet; + } + + @Override + public void onCalled(CollectionObserverPair pair, Object observer) { + //noinspection unchecked + pair.onChange(observer, changeSet); + } + } + + // Called by JNI + @SuppressWarnings("SameParameterValue") + void notifyChangeListeners(long nativeChangeSetPtr); +} diff --git a/realm/realm-library/src/main/java/io/realm/internal/OsList.java b/realm/realm-library/src/main/java/io/realm/internal/OsList.java index aeb60ecb9f..bedf3e928a 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/OsList.java +++ b/realm/realm-library/src/main/java/io/realm/internal/OsList.java @@ -4,16 +4,20 @@ import javax.annotation.Nullable; +import io.realm.OrderedRealmCollectionChangeListener; +import io.realm.RealmChangeListener; /** * Java wrapper of Object Store List class. This backs managed versions of RealmList. */ -public class OsList implements NativeObject { +public class OsList implements NativeObject, ObservableCollection { private final long nativePtr; private final NativeContext context; private final Table targetTable; private static final long nativeFinalizerPtr = nativeGetFinalizerPtr(); + private final ObserverPairList observerPairs = + new ObserverPairList(); public OsList(UncheckedRow row, long columnIndex) { SharedRealm sharedRealm = row.getTable().getSharedRealm(); @@ -212,6 +216,44 @@ public Table getTargetTable() { return targetTable; } + public void addListener(T observer, OrderedRealmCollectionChangeListener listener) { + if (observerPairs.isEmpty()) { + nativeStartListening(nativePtr); + } + CollectionObserverPair collectionObserverPair = new CollectionObserverPair(observer, listener); + observerPairs.add(collectionObserverPair); + } + + public void addListener(T observer, RealmChangeListener listener) { + addListener(observer, new RealmChangeListenerWrapper(listener)); + } + + public void removeListener(T observer, OrderedRealmCollectionChangeListener listener) { + observerPairs.remove(observer, listener); + if (observerPairs.isEmpty()) { + nativeStopListening(nativePtr); + } + } + + public void removeListener(T observer, RealmChangeListener listener) { + removeListener(observer, new RealmChangeListenerWrapper(listener)); + } + + public void removeAllListeners() { + observerPairs.clear(); + nativeStopListening(nativePtr); + } + + // Called by JNI + @Override + public void notifyChangeListeners(long nativeChangeSetPtr) { + if (nativeChangeSetPtr == 0) { + // First time "query" returns. Do nothing. + return; + } + observerPairs.foreach(new Callback(new OsCollectionChangeSet(nativeChangeSetPtr))); + } + private static native long nativeGetFinalizerPtr(); // TODO: nativeTablePtr is not necessary. It is used to create FieldDescriptor which should be generated from @@ -292,4 +334,8 @@ public Table getTargetTable() { private static native void nativeSetString(long nativePtr, long pos, @Nullable String value); private static native Object nativeGetValue(long nativePtr, long pos); + + private native void nativeStartListening(long nativePtr); + + private native void nativeStopListening(long nativePtr); } From 4400ab3e853472dd893b519f7e28b28988ce3fdf Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 15:09:45 +0300 Subject: [PATCH 42/72] stop to add backlink field into nullable field list --- .../src/main/java/io/realm/processor/ClassMetaData.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java index 4bdeff8f68..fd7069205d 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java @@ -474,8 +474,8 @@ private boolean categorizeField(Element element) { // The field doesn't have the @Required and @org.jetbrains.annotations.NotNull annotation. // Without @Required annotation, boxed types/RealmObject/Date/String/bytes should be added to // nullableFields. - // RealmList and Primitive types are NOT nullable always. @Required annotation is not supported. - if (!Utils.isPrimitiveType(field)) { + // RealmList of models, RealmResults(backlinks) and primitive types are NOT nullable. @Required annotation is not supported. + if (!Utils.isPrimitiveType(field) && !Utils.isRealmResults(field)) { nullableFields.add(field); } } From 8c9e60ff69dd0fb11196428206e28e4a6fbc5595 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 15:15:22 +0300 Subject: [PATCH 43/72] add comments to ClassMetaData.hasRequiredAnnotation() and ClassMetaData.isRequiredField() --- .../java/io/realm/processor/ClassMetaData.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java index fd7069205d..3f9cae0b10 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/ClassMetaData.java @@ -501,10 +501,24 @@ private boolean categorizeField(Element element) { return true; } + /** + * This method only checks if the field has {@code @Required} annotation. + * In most cases, you should use {@link #isRequiredField(VariableElement)} to take into account + * Kotlin's annotation as well. + * + * @param field target field. + * @return {@code true} if the field has {@code @Required} annotation, {@code false} otherwise. + * @see #isRequiredField(VariableElement) + */ private boolean hasRequiredAnnotation(VariableElement field) { return field.getAnnotation(Required.class) != null; } + /** + * Checks if the field is annotated as required. + * @param field target field. + * @return {@code true} if the field is annotated as required, {@code false} otherwise. + */ private boolean isRequiredField(VariableElement field) { if (hasRequiredAnnotation(field)) { return true; From 557f216b3d630e41c2b3993d5128770d86915967 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 15:28:04 +0300 Subject: [PATCH 44/72] move Utils.getRealmListElementTypeMirror() to TypeMirrors class. --- .../processor/RealmProxyClassGenerator.java | 10 +++++----- .../java/io/realm/processor/TypeMirrors.java | 12 ++++++++++++ .../src/main/java/io/realm/processor/Utils.java | 16 +++------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index dbbf65cb2a..2a5c3affb6 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -315,7 +315,7 @@ private void emitPersistedFieldAccessors(final JavaWriter writer) throws IOExcep } else if (Utils.isRealmModel(field)) { emitRealmModel(writer, field, fieldName, fieldTypeCanonicalName); } else if (Utils.isRealmList(field)) { - final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + final TypeMirror elementTypeMirror = TypeMirrors.getRealmListElementTypeMirror(field); emitRealmList(writer, field, fieldName, fieldTypeCanonicalName, elementTypeMirror); } else { throw new UnsupportedOperationException(String.format(Locale.US, @@ -1111,7 +1111,7 @@ private void emitInsertMethod(JavaWriter writer) throws IOException { .endControlFlow(); } else if (Utils.isRealmValueList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); - final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + final TypeMirror elementTypeMirror = TypeMirrors.getRealmListElementTypeMirror(field); writer .emitEmptyLine() .emitStatement("RealmList<%s> %sList = ((%s) object).%s()", @@ -1208,7 +1208,7 @@ private void emitInsertListMethod(JavaWriter writer) throws IOException { } else if (Utils.isRealmValueList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); - final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + final TypeMirror elementTypeMirror = TypeMirrors.getRealmListElementTypeMirror(field); writer .emitEmptyLine() .emitStatement("RealmList<%s> %sList = ((%s) object).%s()", @@ -1303,7 +1303,7 @@ private void emitInsertOrUpdateMethod(JavaWriter writer) throws IOException { } else if (Utils.isRealmValueList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); - final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + final TypeMirror elementTypeMirror = TypeMirrors.getRealmListElementTypeMirror(field); writer .emitEmptyLine() .emitStatement("OsList %1$sOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.%1$sIndex)", fieldName) @@ -1406,7 +1406,7 @@ private void emitInsertOrUpdateListMethod(JavaWriter writer) throws IOException } else if (Utils.isRealmValueList(field)) { final String genericType = Utils.getGenericTypeQualifiedName(field); - final TypeMirror elementTypeMirror = Utils.getRealmListElementTypeMirror(field); + final TypeMirror elementTypeMirror = TypeMirrors.getRealmListElementTypeMirror(field); writer .emitEmptyLine() .emitStatement("OsList %1$sOsList = new OsList(table.getUncheckedRow(rowIndex), columnInfo.%1$sIndex)", fieldName) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java index b3652b8cdb..3f7ecafa6e 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java @@ -19,6 +19,8 @@ import java.util.Date; import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; @@ -62,4 +64,14 @@ public TypeMirrors(ProcessingEnvironment env) { PRIMITIVE_SHORT_MIRROR = typeUtils.getPrimitiveType(TypeKind.SHORT); PRIMITIVE_BYTE_MIRROR = typeUtils.getPrimitiveType(TypeKind.BYTE); } + + /** + * @return the {@link TypeMirror} of the elements in {@code RealmList}. + */ + public static TypeMirror getRealmListElementTypeMirror(VariableElement field) { + if (!Utils.isRealmList(field)) { + return null; + } + return ((DeclaredType) field.asType()).getTypeArguments().get(0); + } } diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java index f744a8f12f..24d20531cd 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/Utils.java @@ -164,22 +164,12 @@ public static boolean isRealmList(VariableElement field) { return typeUtils.isAssignable(field.asType(), realmList); } - /** - * @return the {@link TypeMirror} of the elements in {@code RealmList}. - */ - public static TypeMirror getRealmListElementTypeMirror(VariableElement field) { - if (!isRealmList(field)) { - return null; - } - return ((DeclaredType) field.asType()).getTypeArguments().get(0); - } - /** * @param field {@link VariableElement} of a value list field. * @return element type of the list field. */ public static Constants.RealmFieldType getValueListFieldType(VariableElement field) { - final TypeMirror elementTypeMirror = getRealmListElementTypeMirror(field); + final TypeMirror elementTypeMirror = TypeMirrors.getRealmListElementTypeMirror(field); return Constants.LIST_ELEMENT_TYPE_TO_REALM_TYPES.get(elementTypeMirror.toString()); } @@ -188,7 +178,7 @@ public static Constants.RealmFieldType getValueListFieldType(VariableElement fie * {@code false} otherwise. */ public static boolean isRealmModelList(VariableElement field) { - final TypeMirror elementTypeMirror = getRealmListElementTypeMirror(field); + final TypeMirror elementTypeMirror = TypeMirrors.getRealmListElementTypeMirror(field); if (elementTypeMirror == null) { return false; } @@ -200,7 +190,7 @@ public static boolean isRealmModelList(VariableElement field) { * {@code false} otherwise. */ public static boolean isRealmValueList(VariableElement field) { - final TypeMirror elementTypeMirror = getRealmListElementTypeMirror(field); + final TypeMirror elementTypeMirror = TypeMirrors.getRealmListElementTypeMirror(field); if (elementTypeMirror == null) { return false; } From 1fd1b00672c356e4e7cfc0f03177d87817c29cf7 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 15:28:20 +0300 Subject: [PATCH 45/72] fix exception message --- .../main/java/io/realm/processor/RealmProxyClassGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 2a5c3affb6..54ea558099 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -598,7 +598,7 @@ public void emit(JavaWriter writer) throws IOException { } else { writer.beginControlFlow("for (%1$s item : value)", genericType) .beginControlFlow("if (item == null)") - .emitStatement(metadata.isElementNullable(field) ? "osList.addNull()" : "throw new IllegalArgumentException(\"Storing 'null' into " + fieldName + "' is not allowed by schema.\")") + .emitStatement(metadata.isElementNullable(field) ? "osList.addNull()" : "throw new IllegalArgumentException(\"Storing 'null' into " + fieldName + "' is not allowed by the schema.\")") .nextControlFlow("else") .emitStatement(getStatementForAppendingValueToOsList("osList", "item", elementTypeMirror)) .endControlFlow() From c036e8c41b255cf273f1a0c597b3997888221368 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 15:37:54 +0300 Subject: [PATCH 46/72] add class comment to TypeMirrors --- .../java/io/realm/processor/TypeMirrors.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java index 3f7ecafa6e..8757727a14 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/TypeMirrors.java @@ -27,24 +27,27 @@ import javax.lang.model.util.Types; -public class TypeMirrors { - public final TypeMirror STRING_MIRROR; - public final TypeMirror BINARY_MIRROR; - public final TypeMirror BOOLEAN_MIRROR; - public final TypeMirror LONG_MIRROR; - public final TypeMirror INTEGER_MIRROR; - public final TypeMirror SHORT_MIRROR; - public final TypeMirror BYTE_MIRROR; - public final TypeMirror DOUBLE_MIRROR; - public final TypeMirror FLOAT_MIRROR; - public final TypeMirror DATE_MIRROR; +/** + * This class provides {@link TypeMirror} instances used in annotation processor. + */ +class TypeMirrors { + final TypeMirror STRING_MIRROR; + final TypeMirror BINARY_MIRROR; + final TypeMirror BOOLEAN_MIRROR; + final TypeMirror LONG_MIRROR; + final TypeMirror INTEGER_MIRROR; + final TypeMirror SHORT_MIRROR; + final TypeMirror BYTE_MIRROR; + final TypeMirror DOUBLE_MIRROR; + final TypeMirror FLOAT_MIRROR; + final TypeMirror DATE_MIRROR; - public final TypeMirror PRIMITIVE_LONG_MIRROR; - public final TypeMirror PRIMITIVE_INT_MIRROR; - public final TypeMirror PRIMITIVE_SHORT_MIRROR; - public final TypeMirror PRIMITIVE_BYTE_MIRROR; + final TypeMirror PRIMITIVE_LONG_MIRROR; + final TypeMirror PRIMITIVE_INT_MIRROR; + final TypeMirror PRIMITIVE_SHORT_MIRROR; + final TypeMirror PRIMITIVE_BYTE_MIRROR; - public TypeMirrors(ProcessingEnvironment env) { + TypeMirrors(ProcessingEnvironment env) { final Types typeUtils = env.getTypeUtils(); final Elements elementUtils = env.getElementUtils(); From 76cbde43b16f54c2d852031af197a9ea4bc303bb Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Thu, 14 Sep 2017 15:49:16 +0300 Subject: [PATCH 47/72] add TODO comment --- .../processor/RealmProxyClassGenerator.java | 5 +- .../io/realm/AllTypesRealmProxy.java | 20 +++++++ .../io/realm/NullTypesRealmProxy.java | 60 +++++++++++++++---- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 54ea558099..4d646b982a 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -1958,7 +1958,8 @@ private void emitCreateOrUpdateUsingJsonObject(JavaWriter writer) throws IOExcep } else if (Utils.isRealmValueList(field)) { // FIXME need to implement logic for value list fields. - + writer.emitSingleLineComment(String.format(Locale.ENGLISH, + "TODO implement logic for value list%1$s.", field.getSimpleName())); } else if (Utils.isMutableRealmInteger(field)) { RealmJsonTypeHelper.emitFillJavaTypeWithJsonValue( "objProxy", @@ -2042,7 +2043,7 @@ private void emitCreateUsingJsonStream(JavaWriter writer) throws IOException { } else if (Utils.isRealmValueList(field)) { // FIXME need to implement logic for value list fields. - + writer.emitSingleLineComment("TODO implement logic for value list."); } else if (Utils.isMutableRealmInteger(field)) { RealmJsonTypeHelper.emitFillJavaTypeFromStream( "objProxy", diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java index 87193b8d6f..673f2ba1ae 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/AllTypesRealmProxy.java @@ -1044,6 +1044,16 @@ public static some.test.AllTypes createOrUpdateUsingJsonObject(Realm realm, JSON } } } + // TODO implement logic for value listcolumnStringList. + // TODO implement logic for value listcolumnBinaryList. + // TODO implement logic for value listcolumnBooleanList. + // TODO implement logic for value listcolumnLongList. + // TODO implement logic for value listcolumnIntegerList. + // TODO implement logic for value listcolumnShortList. + // TODO implement logic for value listcolumnByteList. + // TODO implement logic for value listcolumnDoubleList. + // TODO implement logic for value listcolumnFloatList. + // TODO implement logic for value listcolumnDateList. return obj; } @@ -1143,15 +1153,25 @@ public static some.test.AllTypes createUsingJsonStream(Realm realm, JsonReader r reader.endArray(); } } else if (name.equals("columnStringList")) { + // TODO implement logic for value list. } else if (name.equals("columnBinaryList")) { + // TODO implement logic for value list. } else if (name.equals("columnBooleanList")) { + // TODO implement logic for value list. } else if (name.equals("columnLongList")) { + // TODO implement logic for value list. } else if (name.equals("columnIntegerList")) { + // TODO implement logic for value list. } else if (name.equals("columnShortList")) { + // TODO implement logic for value list. } else if (name.equals("columnByteList")) { + // TODO implement logic for value list. } else if (name.equals("columnDoubleList")) { + // TODO implement logic for value list. } else if (name.equals("columnFloatList")) { + // TODO implement logic for value list. } else if (name.equals("columnDateList")) { + // TODO implement logic for value list. } else { reader.skipValue(); } diff --git a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java index 729ac04210..43544b3e1e 100644 --- a/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java +++ b/realm/realm-annotations-processor/src/test/resources/io/realm/NullTypesRealmProxy.java @@ -958,7 +958,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.lang.String item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldStringListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldStringListNotNull' is not allowed by the schema."); } else { osList.addString(item); } @@ -1036,7 +1036,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (byte[] item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldBinaryListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldBinaryListNotNull' is not allowed by the schema."); } else { osList.addBinary(item); } @@ -1114,7 +1114,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.lang.Boolean item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldBooleanListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldBooleanListNotNull' is not allowed by the schema."); } else { osList.addBoolean(item); } @@ -1192,7 +1192,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.lang.Long item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldLongListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldLongListNotNull' is not allowed by the schema."); } else { osList.addLong(item.longValue()); } @@ -1270,7 +1270,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.lang.Integer item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldIntegerListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldIntegerListNotNull' is not allowed by the schema."); } else { osList.addLong(item.longValue()); } @@ -1348,7 +1348,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.lang.Short item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldShortListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldShortListNotNull' is not allowed by the schema."); } else { osList.addLong(item.longValue()); } @@ -1426,7 +1426,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.lang.Byte item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldByteListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldByteListNotNull' is not allowed by the schema."); } else { osList.addLong(item.longValue()); } @@ -1504,7 +1504,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.lang.Double item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldDoubleListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldDoubleListNotNull' is not allowed by the schema."); } else { osList.addDouble(item.doubleValue()); } @@ -1582,7 +1582,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.lang.Float item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldFloatListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldFloatListNotNull' is not allowed by the schema."); } else { osList.addFloat(item.floatValue()); } @@ -1660,7 +1660,7 @@ protected final void copy(ColumnInfo rawSrc, ColumnInfo rawDst) { } for (java.util.Date item : value) { if (item == null) { - throw new IllegalArgumentException("Storing 'null' into fieldDateListNotNull' is not allowed by schema."); + throw new IllegalArgumentException("Storing 'null' into fieldDateListNotNull' is not allowed by the schema."); } else { osList.addDate(item); } @@ -1996,6 +1996,26 @@ public static some.test.NullTypes createOrUpdateUsingJsonObject(Realm realm, JSO objProxy.realmSet$fieldObjectNull(fieldObjectNullObj); } } + // TODO implement logic for value listfieldStringListNotNull. + // TODO implement logic for value listfieldStringListNull. + // TODO implement logic for value listfieldBinaryListNotNull. + // TODO implement logic for value listfieldBinaryListNull. + // TODO implement logic for value listfieldBooleanListNotNull. + // TODO implement logic for value listfieldBooleanListNull. + // TODO implement logic for value listfieldLongListNotNull. + // TODO implement logic for value listfieldLongListNull. + // TODO implement logic for value listfieldIntegerListNotNull. + // TODO implement logic for value listfieldIntegerListNull. + // TODO implement logic for value listfieldShortListNotNull. + // TODO implement logic for value listfieldShortListNull. + // TODO implement logic for value listfieldByteListNotNull. + // TODO implement logic for value listfieldByteListNull. + // TODO implement logic for value listfieldDoubleListNotNull. + // TODO implement logic for value listfieldDoubleListNull. + // TODO implement logic for value listfieldFloatListNotNull. + // TODO implement logic for value listfieldFloatListNull. + // TODO implement logic for value listfieldDateListNotNull. + // TODO implement logic for value listfieldDateListNull. return obj; } @@ -2168,25 +2188,45 @@ public static some.test.NullTypes createUsingJsonStream(Realm realm, JsonReader objProxy.realmSet$fieldObjectNull(fieldObjectNullObj); } } else if (name.equals("fieldStringListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldStringListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldBinaryListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldBinaryListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldBooleanListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldBooleanListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldLongListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldLongListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldIntegerListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldIntegerListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldShortListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldShortListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldByteListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldByteListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldDoubleListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldDoubleListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldFloatListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldFloatListNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldDateListNotNull")) { + // TODO implement logic for value list. } else if (name.equals("fieldDateListNull")) { + // TODO implement logic for value list. } else { reader.skipValue(); } From db550a7adeacd37fe67db010e6cbc1819f5c4a8e Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Fri, 15 Sep 2017 08:43:25 +0300 Subject: [PATCH 48/72] remove outdate comment --- .../realm-library/src/main/java/io/realm/internal/Property.java | 1 - 1 file changed, 1 deletion(-) diff --git a/realm/realm-library/src/main/java/io/realm/internal/Property.java b/realm/realm-library/src/main/java/io/realm/internal/Property.java index 222db2c057..03a1026223 100644 --- a/realm/realm-library/src/main/java/io/realm/internal/Property.java +++ b/realm/realm-library/src/main/java/io/realm/internal/Property.java @@ -72,7 +72,6 @@ public class Property implements NativeObject { } Property(String name, RealmFieldType type, String linkedClassName) { - // Ignore the isRequired when creating the linking property. this(nativeCreatePersistedLinkProperty(name, convertFromRealmFieldType(type, false), linkedClassName)); } From 078041adbaf5862ecb7b814496405ac608fab4ad Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Fri, 15 Sep 2017 10:25:14 +0300 Subject: [PATCH 49/72] fix todo comment --- .../main/java/io/realm/processor/RealmProxyClassGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java index 4d646b982a..809c82bbba 100644 --- a/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java +++ b/realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.java @@ -1959,7 +1959,7 @@ private void emitCreateOrUpdateUsingJsonObject(JavaWriter writer) throws IOExcep } else if (Utils.isRealmValueList(field)) { // FIXME need to implement logic for value list fields. writer.emitSingleLineComment(String.format(Locale.ENGLISH, - "TODO implement logic for value list%1$s.", field.getSimpleName())); + "TODO implement logic for value list %1$s.", field.getSimpleName())); } else if (Utils.isMutableRealmInteger(field)) { RealmJsonTypeHelper.emitFillJavaTypeWithJsonValue( "objProxy", From 7874296fa3c96a025b64269825a895b462b53358 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sat, 16 Sep 2017 10:57:13 +0300 Subject: [PATCH 50/72] fix failing test --- .../io/realm/OrderedRealmCollectionIteratorTests.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/OrderedRealmCollectionIteratorTests.java b/realm/realm-library/src/androidTest/java/io/realm/OrderedRealmCollectionIteratorTests.java index 534730bb58..d7e705a0fd 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/OrderedRealmCollectionIteratorTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/OrderedRealmCollectionIteratorTests.java @@ -642,16 +642,21 @@ public void listIterator_unsupportedMethods() { fail(); } catch (UnsupportedOperationException e) { assertResultsOrSnapshot(); - } catch (IllegalStateException e) { + } catch (IllegalStateException e) { // since next() was never called. assertRealmList(); } try { it.add(null); - fail(); + if (collectionClass != CollectionClass.UNMANAGED_REALMLIST) { + fail(); + } } catch (UnsupportedOperationException e) { assertResultsOrSnapshot(); } catch (IllegalArgumentException e) { + if (collectionClass == CollectionClass.UNMANAGED_REALMLIST) { + fail(); + } assertRealmList(); } @@ -660,7 +665,7 @@ public void listIterator_unsupportedMethods() { fail(); } catch (UnsupportedOperationException e) { assertResultsOrSnapshot(); - } catch (IllegalStateException e) { + } catch (IllegalStateException e) { // since the collection is empty assertRealmList(); } } From eebf152cc9e7ab8ea1b18ef7f5d22b443928c35c Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sat, 16 Sep 2017 11:02:03 +0300 Subject: [PATCH 51/72] remove methods to return primitive array --- ...ManagedRealmListForValue_toArrayTests.java | 336 ------------------ .../src/main/java/io/realm/RealmList.java | 331 ----------------- 2 files changed, 667 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java index dd383a4242..0fd8a58ef1 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java @@ -212,342 +212,6 @@ public void tearDown() throws Exception { NON_NUMBER_LIST_TYPES = Collections.unmodifiableSet(set); } - @Test - public void toLongArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toLongArray(); - // should not reach here - return; - } - - final long[] expected = new long[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (long) generateValue(LONG_LIST, i); - expected[i * 2 + 1] = 0L; - } else { - expected[i] = (long) generateValue(LONG_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toLongArray())); - } - - @Test - public void toLongArrayWithNullValue() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - final long valueForNull = Long.MIN_VALUE; - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toLongArray(valueForNull); - // should not reach here - return; - } - - final long[] expected = new long[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (long) generateValue(LONG_LIST, i); - expected[i * 2 + 1] = valueForNull; - } else { - expected[i] = (long) generateValue(LONG_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toLongArray(valueForNull))); - } - - @Test - public void toIntArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toIntArray(); - // should not reach here - return; - } - - final int[] expected = new int[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (int) generateValue(INTEGER_LIST, i); - expected[i * 2 + 1] = 0; - } else { - expected[i] = (int) generateValue(INTEGER_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toIntArray())); - } - - @Test - public void toIntArrayWithNullValue() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - final int valueForNull = Integer.MIN_VALUE; - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toIntArray(valueForNull); - // should not reach here - return; - } - - final int[] expected = new int[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (int) generateValue(INTEGER_LIST, i); - expected[i * 2 + 1] = valueForNull; - } else { - expected[i] = (int) generateValue(INTEGER_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toIntArray(valueForNull))); - } - - @Test - public void toShortArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toShortArray(); - // should not reach here - return; - } - - final short[] expected = new short[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (short) generateValue(SHORT_LIST, i); - expected[i * 2 + 1] = 0; - } else { - expected[i] = (short) generateValue(SHORT_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toShortArray())); - } - - @Test - public void toShortArrayWithNullValue() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - final short valueForNull = Short.MIN_VALUE; - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toShortArray(valueForNull); - // should not reach here - return; - } - - final short[] expected = new short[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (short) generateValue(SHORT_LIST, i); - expected[i * 2 + 1] = valueForNull; - } else { - expected[i] = (short) generateValue(SHORT_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toShortArray(valueForNull))); - } - - @Test - public void toByteArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toByteArray(); - // should not reach here - return; - } - - final byte[] expected = new byte[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (byte) generateValue(BYTE_LIST, i); - expected[i * 2 + 1] = 0; - } else { - expected[i] = (byte) generateValue(BYTE_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toByteArray())); - } - - @Test - public void toByteArrayWithNullValue() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - final byte valueForNull = Byte.MIN_VALUE; - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toByteArray(valueForNull); - // should not reach here - return; - } - - final byte[] expected = new byte[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (byte) generateValue(BYTE_LIST, i); - expected[i * 2 + 1] = valueForNull; - } else { - expected[i] = (byte) generateValue(BYTE_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toByteArray(valueForNull))); - } - - @Test - public void toDoubleArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toDoubleArray(); - // should not reach here - return; - } - - final double[] expected = new double[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (double) generateValue(DOUBLE_LIST, i); - expected[i * 2 + 1] = 0D; - } else { - expected[i] = (double) generateValue(DOUBLE_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toDoubleArray())); - } - - @Test - public void toDoubleArrayWithNullValue() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - final double valueForNull = Double.NEGATIVE_INFINITY; - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toDoubleArray(valueForNull); - // should not reach here - return; - } - - final double[] expected = new double[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (double) generateValue(DOUBLE_LIST, i); - expected[i * 2 + 1] = valueForNull; - } else { - expected[i] = (double) generateValue(DOUBLE_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toDoubleArray(valueForNull))); - } - - @Test - public void toFloatArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toFloatArray(); - // should not reach here - return; - } - - final float[] expected = new float[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (float) generateValue(FLOAT_LIST, i); - expected[i * 2 + 1] = 0L; - } else { - expected[i] = (float) generateValue(FLOAT_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toFloatArray())); - } - - @Test - public void toFloatArrayWithNullValue() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - final float valueForNull = Float.NEGATIVE_INFINITY; - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toFloatArray(valueForNull); - // should not reach here - return; - } - - final float[] expected = new float[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (float) generateValue(FLOAT_LIST, i); - expected[i * 2 + 1] = valueForNull; - } else { - expected[i] = (float) generateValue(FLOAT_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toFloatArray(valueForNull))); - } - - @Test - public void toBooleanArray() { - final boolean exceptionExpected = (listType != BOOLEAN_LIST); - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toBooleanArray(); - // should not reach here - return; - } - - final boolean[] expected = new boolean[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (boolean) generateValue(BOOLEAN_LIST, i); - expected[i * 2 + 1] = false; - } else { - expected[i] = (boolean) generateValue(BOOLEAN_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toBooleanArray())); - } - - @Test - public void toBooleanArrayWithNullValue() { - final boolean exceptionExpected = (listType != BOOLEAN_LIST); - - final boolean valueForNull = true; - - if (exceptionExpected) { - thrown.expect(IllegalStateException.class); - list.toBooleanArray(valueForNull); - // should not reach here - return; - } - - final boolean[] expected = new boolean[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; - for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { - if (typeIsNullable) { - expected[i * 2] = (boolean) generateValue(BOOLEAN_LIST, i); - expected[i * 2 + 1] = valueForNull; - } else { - expected[i] = (boolean) generateValue(BOOLEAN_LIST, i); - } - } - assertTrue(Arrays.equals(expected, list.toBooleanArray(valueForNull))); - } - @Test public void toArray() { final Object[] expected = new Object[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 0bdafd4c52..efbbef4014 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -1502,337 +1502,6 @@ public T[] toArray(T[] a) { return super.toArray(a); } - /** - * Returns newly allocated {@code long} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code valueForNull} is used instead. - * - * @return newly allocated {@code long} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toLongArray() - * @see #toArray() - * @see #toArray(Object[]) - */ - @SuppressWarnings("WeakerAccess") - public long[] toLongArray(@SuppressWarnings("SameParameterValue") long valueForNull) { - if (!isManaged()) { - throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); - } - if (clazz == null || !Number.class.isAssignableFrom(clazz)) { - throw new IllegalStateException("toLongArray() is only supported when the element type is implementing 'java.lang.Number' interface."); - } - final int size = size(); - final long[] result = new long[size]; - for (int i = 0; i < size; i++) { - final E element = osListOperator.get(i); - result[i] = (element == null) ? valueForNull : ((Number) element).longValue(); - } - return result; - } - - /** - * Returns newly allocated {@code long} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code 0L} is used instead. - * - * @return newly allocated {@code long} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toLongArray(long) - * @see #toArray() - * @see #toArray(Object[]) - */ - public long[] toLongArray() { - return toLongArray(0L); - } - - /** - * Returns newly allocated {@code int} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code valueForNull} is used instead. - * - * @return newly allocated {@code int} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toIntArray() - * @see #toArray() - * @see #toArray(Object[]) - */ - @SuppressWarnings("WeakerAccess") - public int[] toIntArray(@SuppressWarnings("SameParameterValue") int valueForNull) { - if (!isManaged()) { - throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); - } - if (clazz == null || !Number.class.isAssignableFrom(clazz)) { - throw new IllegalStateException("toIntArray() is only supported when the element type is implementing 'java.lang.Number' interface."); - } - final int size = size(); - final int[] result = new int[size]; - for (int i = 0; i < size; i++) { - final E element = osListOperator.get(i); - result[i] = (element == null) ? valueForNull : ((Number) element).intValue(); - } - return result; - } - - /** - * Returns newly allocated {@code int} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code 0} is used instead. - * - * @return newly allocated {@code int} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toIntArray(int) - * @see #toArray() - * @see #toArray(Object[]) - */ - public int[] toIntArray() { - return toIntArray(0); - } - - /** - * Returns newly allocated {@code short} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code valueForNull} is used instead. - * - * @return newly allocated {@code short} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toShortArray() - * @see #toArray() - * @see #toArray(Object[]) - */ - @SuppressWarnings("WeakerAccess") - public short[] toShortArray(@SuppressWarnings("SameParameterValue") short valueForNull) { - if (!isManaged()) { - throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); - } - if (clazz == null || !Number.class.isAssignableFrom(clazz)) { - throw new IllegalStateException("toShortArray() is only supported when the element type is implementing 'java.lang.Number' interface."); - } - final int size = size(); - final short[] result = new short[size]; - for (int i = 0; i < size; i++) { - final E element = osListOperator.get(i); - result[i] = (element == null) ? valueForNull : ((Number) element).shortValue(); - } - return result; - } - - /** - * Returns newly allocated {@code short} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code (short) 0} is used instead. - * - * @return newly allocated {@code short} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toShortArray(short) - * @see #toArray() - * @see #toArray(Object[]) - */ - public short[] toShortArray() { - return toShortArray((short) 0); - } - - /** - * Returns newly allocated {@code byte} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code valueForNull} is used instead. - * - * @return newly allocated {@code byte} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toByteArray() - * @see #toArray() - * @see #toArray(Object[]) - */ - @SuppressWarnings("WeakerAccess") - public byte[] toByteArray(@SuppressWarnings("SameParameterValue") byte valueForNull) { - if (!isManaged()) { - throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); - } - if (clazz == null || !Number.class.isAssignableFrom(clazz)) { - throw new IllegalStateException("toByteArray() is only supported when the element type is implementing 'java.lang.Number' interface."); - } - final int size = size(); - final byte[] result = new byte[size]; - for (int i = 0; i < size; i++) { - final E element = osListOperator.get(i); - result[i] = (element == null) ? valueForNull : ((Number) element).byteValue(); - } - return result; - } - - /** - * Returns newly allocated {@code byte} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code (byte) 0} is used instead. - * - * @return newly allocated {@code byte} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toByteArray(byte) - * @see #toArray() - * @see #toArray(Object[]) - */ - public byte[] toByteArray() { - return toByteArray((byte) 0); - } - - /** - * Returns newly allocated {@code boolean} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code valueForNull} is used instead. - * - * @return newly allocated {@code boolean} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toBooleanArray() - * @see #toArray() - * @see #toArray(Object[]) - */ - @SuppressWarnings("WeakerAccess") - public boolean[] toBooleanArray(@SuppressWarnings("SameParameterValue") boolean valueForNull) { - if (!isManaged()) { - throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); - } - if (clazz != Boolean.class) { - throw new IllegalStateException("toBooleanArray() is only supported when the element type is 'java.lang.Boolean'."); - } - final int size = size(); - final boolean[] result = new boolean[size]; - for (int i = 0; i < size; i++) { - final E element = osListOperator.get(i); - result[i] = (element == null) ? valueForNull : (Boolean) element; - } - return result; - } - - /** - * Returns newly allocated {@code boolean} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code false} is used instead. - * - * @return newly allocated {@code boolean} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toBooleanArray(boolean) - * @see #toArray() - * @see #toArray(Object[]) - */ - public boolean[] toBooleanArray() { - return toBooleanArray(false); - } - - /** - * Returns newly allocated {@code double} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code valueForNull} is used instead. - * - * @return newly allocated {@code double} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toDoubleArray() - * @see #toArray() - * @see #toArray(Object[]) - */ - @SuppressWarnings("WeakerAccess") - public double[] toDoubleArray(@SuppressWarnings("SameParameterValue") double valueForNull) { - if (!isManaged()) { - throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); - } - if (clazz == null || !Number.class.isAssignableFrom(clazz)) { - throw new IllegalStateException("toDoubleArray() is only supported when the element type is implementing 'java.lang.Number' interface."); - } - - final int size = size(); - final double[] result = new double[size]; - for (int i = 0; i < size; i++) { - final E element = osListOperator.get(i); - result[i] = (element == null) ? valueForNull : ((Number) element).doubleValue(); - } - return result; - } - - /** - * Returns newly allocated {@code double} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code 0D} is used instead. - * - * @return newly allocated {@code double} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toDoubleArray(double) - * @see #toArray() - * @see #toArray(Object[]) - */ - public double[] toDoubleArray() { - return toDoubleArray(0D); - } - - /** - * Returns newly allocated {@code float} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code valueForNull} is used instead. - * - * @return newly allocated {@code float} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toFloatArray() - * @see #toArray() - * @see #toArray(Object[]) - */ - @SuppressWarnings("WeakerAccess") - public float[] toFloatArray(@SuppressWarnings("SameParameterValue") float valueForNull) { - if (!isManaged()) { - throw new IllegalStateException(ONLY_IN_MANAGED_MODE_MESSAGE); - } - if (clazz == null || !Number.class.isAssignableFrom(clazz)) { - throw new IllegalStateException("toFloatArray() is only supported when the element type is implementing 'java.lang.Number' interface."); - } - - final int size = size(); - final float[] result = new float[size]; - for (int i = 0; i < size; i++) { - final E element = osListOperator.get(i); - result[i] = (element == null) ? valueForNull : ((Number) element).floatValue(); - } - return result; - } - - /** - * Returns newly allocated {@code float} array that contains all values in this {@link RealmList}. - *

- * This method is available only when the list is managed and the element type is implementing {@link Number} interface. - *

- * If this list contains {@code null} value, {@code 0F} is used instead. - * - * @return newly allocated {@code float} array. - * @throws IllegalStateException if this {@link RealmList} is not managed or element type is not implementing {@link Number}. - * @see #toFloatArray(float) - * @see #toArray() - * @see #toArray(Object[]) - */ - public float[] toFloatArray() { - return toFloatArray(0F); - } - private static boolean isClassForRealmModel(Class clazz) { return RealmModel.class.isAssignableFrom(clazz); } From bb43a16d966895faf0bf6079aa4621721f80e59c Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sat, 16 Sep 2017 15:33:55 +0300 Subject: [PATCH 52/72] Using constans defined in Table class --- .../java/io/realm/ManagedRealmListForValueTests.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index a2492a3537..b5e7d30565 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -37,6 +37,7 @@ import javax.annotation.Nullable; import io.realm.entities.NullTypes; +import io.realm.internal.Table; import io.realm.rule.RunInLooperThread; import io.realm.rule.RunTestInLooperThread; import io.realm.rule.TestRealmConfigurationFactory; @@ -394,10 +395,6 @@ public void isValid_whenParentRemoved() { assertFalse(list.isValid()); } - private static final int HEADER_SIZE = 8; - private static final int MAX_STRING_SIZE = 0xFFFFF8 - HEADER_SIZE - 1; - private static final int MAX_BINARY_SIZE = 0xFFFFF8 - HEADER_SIZE; - @Test public void add_exceedingSizeLimitValueThrows() { if (listType != STRING_LIST && listType != BINARY_LIST) { @@ -407,10 +404,10 @@ public void add_exceedingSizeLimitValueThrows() { final int sizeLimit; switch (listType) { case STRING_LIST: - sizeLimit = MAX_STRING_SIZE; + sizeLimit = Table.MAX_STRING_SIZE; break; case BINARY_LIST: - sizeLimit = MAX_BINARY_SIZE; + sizeLimit = Table.MAX_BINARY_SIZE; break; default: throw new AssertionError("Unexpected list type: " + listType.name()); From 4f5cb689e94f3698587e2107708401272ba39a41 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sat, 16 Sep 2017 15:40:35 +0300 Subject: [PATCH 53/72] use assertArrayEquals() instead of assertTrue(Arrays.equals()) --- .../realm/ManagedRealmListForValueTests.java | 5 ++-- ...ManagedRealmListForValue_toArrayTests.java | 25 ++++++++++--------- .../androidTest/java/io/realm/RealmTests.java | 18 ++++++------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index b5e7d30565..1b6da741d7 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -53,6 +53,7 @@ import static io.realm.ManagedRealmListForValueTests.ListType.SHORT_LIST; import static io.realm.ManagedRealmListForValueTests.ListType.STRING_LIST; import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -311,7 +312,7 @@ private void assertValueEquals(@Nullable Object expected, @Nullable Object actua private void assertValueEquals(@SuppressWarnings("SameParameterValue") @Nullable String message, @Nullable Object expected, @Nullable Object actual) { if (listType == BINARY_LIST) { - assertTrue(message, Arrays.equals((byte[]) expected, (byte[]) actual)); + assertArrayEquals(message, (byte[]) expected, (byte[]) actual); } else { assertEquals(message, expected, actual); } @@ -330,7 +331,7 @@ public void readValues() { } break; case BINARY_LIST: { - assertTrue(Arrays.equals((byte[]) generateValue(BINARY_LIST, i), (byte[]) list.get(typeIsNullable ? (i * 2) : i))); + assertArrayEquals((byte[]) generateValue(BINARY_LIST, i), (byte[]) list.get(typeIsNullable ? (i * 2) : i)); } break; case LONG_LIST: { diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java index 0fd8a58ef1..aea0079673 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java @@ -52,6 +52,7 @@ import static io.realm.ManagedRealmListForValueTests.NULLABLE_TEST_SIZE; import static io.realm.ManagedRealmListForValueTests.generateValue; import static io.realm.ManagedRealmListForValueTests.getListFor; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -225,7 +226,7 @@ public void toArray() { } if (listType != BINARY_LIST) { - assertTrue(Arrays.equals(expected, list.toArray())); + assertArrayEquals(expected, list.toArray()); } else { final Object[] array = list.toArray(); assertEquals(expected.length, array.length); @@ -234,7 +235,7 @@ public void toArray() { assertNull(array[i]); } else { assertTrue(array[i] instanceof byte[]); - assertTrue(Arrays.equals((byte[]) expected[i], (byte[]) array[i])); + assertArrayEquals((byte[]) expected[i], (byte[]) array[i]); } } } @@ -262,7 +263,7 @@ public void toArray_withStringArray() { } final Object[] returnedArray = list.toArray(new String[0]); assertEquals(String.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } @Test @@ -288,7 +289,7 @@ public void toArray_withBooleanArray() { final Object[] returnedArray = list.toArray(new Boolean[0]); assertEquals(Boolean.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } @Test @@ -320,7 +321,7 @@ public void toArray_withBinaryArray() { assertNull(returnedArray[i]); } else { assertTrue(returnedArray[i] instanceof byte[]); - assertTrue(Arrays.equals(expected[i], (byte[]) returnedArray[i])); + assertArrayEquals(expected[i], (byte[]) returnedArray[i]); } } } @@ -347,7 +348,7 @@ public void toArray_withLongArray() { } final Object[] returnedArray = list.toArray(new Long[0]); assertEquals(Long.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } @Test @@ -372,7 +373,7 @@ public void toArray_withIntegerArray() { } final Object[] returnedArray = list.toArray(new Integer[0]); assertEquals(Integer.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } @Test @@ -397,7 +398,7 @@ public void toArray_withShortArray() { } final Object[] returnedArray = list.toArray(new Short[0]); assertEquals(Short.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } @Test @@ -422,7 +423,7 @@ public void toArray_withByteArray() { } final Object[] returnedArray = list.toArray(new Byte[0]); assertEquals(Byte.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } @Test @@ -447,7 +448,7 @@ public void toArray_withDoubleArray() { } final Object[] returnedArray = list.toArray(new Double[0]); assertEquals(Double.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } @Test @@ -472,7 +473,7 @@ public void toArray_withFloatArray() { } final Object[] returnedArray = list.toArray(new Float[0]); assertEquals(Float.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } @Test @@ -497,6 +498,6 @@ public void toArray_withDateArray() { } final Object[] returnedArray = list.toArray(new Date[0]); assertEquals(Date.class, returnedArray.getClass().getComponentType()); - assertTrue(Arrays.equals(expected, returnedArray)); + assertArrayEquals(expected, returnedArray); } } \ No newline at end of file diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java index 197db26252..37d51b8bcd 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmTests.java @@ -1329,7 +1329,7 @@ public void copyToRealm() { assertEquals(1, realmTypes.getColumnBooleanList().size()); assertEquals(true, realmTypes.getColumnBooleanList().get(0)); assertEquals(1, realmTypes.getColumnBinaryList().size()); - assertTrue(Arrays.equals(new byte[] {1}, realmTypes.getColumnBinaryList().get(0))); + assertArrayEquals(new byte[] {1}, realmTypes.getColumnBinaryList().get(0)); assertEquals(1, realmTypes.getColumnLongList().size()); assertEquals((Long) 1L, realmTypes.getColumnLongList().get(0)); assertEquals(1, realmTypes.getColumnDoubleList().size()); @@ -1794,8 +1794,8 @@ public void execute(Realm realm) { assertEquals(true, obj.getColumnBooleanList().get(0)); assertEquals(false, obj.getColumnBooleanList().get(1)); assertEquals(2, obj.getColumnBinaryList().size()); - assertTrue(Arrays.equals(new byte[] {2}, obj.getColumnBinaryList().get(0))); - assertTrue(Arrays.equals(new byte[] {3}, obj.getColumnBinaryList().get(1))); + assertArrayEquals(new byte[] {2}, obj.getColumnBinaryList().get(0)); + assertArrayEquals(new byte[] {3}, obj.getColumnBinaryList().get(1)); assertEquals(2, obj.getColumnLongList().size()); assertEquals((Long) 2L, obj.getColumnLongList().get(0)); assertEquals((Long) 3L, obj.getColumnLongList().get(1)); @@ -2855,7 +2855,7 @@ public void copyToRealm_defaultValuesAreIgnored() { assertEquals(fieldDoubleValue, managedObj.getFieldDouble(), 0D); assertEquals(fieldBooleanValue, managedObj.isFieldBoolean()); assertEquals(fieldDateValue, managedObj.getFieldDate()); - assertTrue(Arrays.equals(fieldBinaryValue, managedObj.getFieldBinary())); + assertArrayEquals(fieldBinaryValue, managedObj.getFieldBinary()); assertEquals(fieldObjectIntValue, managedObj.getFieldObject().getFieldInt()); assertEquals(1, managedObj.getFieldList().size()); assertEquals(fieldListIntValue, managedObj.getFieldList().first().getFieldInt()); @@ -2867,8 +2867,8 @@ public void copyToRealm_defaultValuesAreIgnored() { assertEquals(true, managedObj.getFieldBooleanList().get(0)); assertEquals(false, managedObj.getFieldBooleanList().get(1)); assertEquals(2, managedObj.getFieldBinaryList().size()); - assertTrue(Arrays.equals(new byte[] {2}, managedObj.getFieldBinaryList().get(0))); - assertTrue(Arrays.equals(new byte[] {3}, managedObj.getFieldBinaryList().get(1))); + assertArrayEquals(new byte[] {2}, managedObj.getFieldBinaryList().get(0)); + assertArrayEquals(new byte[] {3}, managedObj.getFieldBinaryList().get(1)); assertEquals(2, managedObj.getFieldLongList().size()); assertEquals((Long) 2L, managedObj.getFieldLongList().get(0)); assertEquals((Long) 3L, managedObj.getFieldLongList().get(1)); @@ -2954,7 +2954,7 @@ public void copyFromRealm_defaultValuesAreIgnored() { assertEquals(managedObj.getFieldDouble(), copy.getFieldDouble(), 0D); assertEquals(managedObj.isFieldBoolean(), copy.isFieldBoolean()); assertEquals(managedObj.getFieldDate(), copy.getFieldDate()); - assertTrue(Arrays.equals(managedObj.getFieldBinary(), copy.getFieldBinary())); + assertArrayEquals(managedObj.getFieldBinary(), copy.getFieldBinary()); assertEquals(managedObj.getFieldObject().getFieldInt(), copy.getFieldObject().getFieldInt()); assertEquals(1, copy.getFieldList().size()); //noinspection ConstantConditions @@ -2967,8 +2967,8 @@ public void copyFromRealm_defaultValuesAreIgnored() { assertEquals(true, managedObj.getFieldBooleanList().get(0)); assertEquals(false, managedObj.getFieldBooleanList().get(1)); assertEquals(2, managedObj.getFieldBinaryList().size()); - assertTrue(Arrays.equals(new byte[] {2}, managedObj.getFieldBinaryList().get(0))); - assertTrue(Arrays.equals(new byte[] {3}, managedObj.getFieldBinaryList().get(1))); + assertArrayEquals(new byte[] {2}, managedObj.getFieldBinaryList().get(0)); + assertArrayEquals(new byte[] {3}, managedObj.getFieldBinaryList().get(1)); assertEquals(2, managedObj.getFieldLongList().size()); assertEquals((Long) 2L, managedObj.getFieldLongList().get(0)); assertEquals((Long) 3L, managedObj.getFieldLongList().get(1)); From 5e0b43c6d9ad420e7e96fa24610804fdd1b70b38 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sun, 17 Sep 2017 03:26:14 +0900 Subject: [PATCH 54/72] add changelog entry about removed methods --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fe5b41b83..2400e9ebe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Breaking Changes * `RealmResults.distinct()`/`RealmResults.distinctAsync()` have been removed. Use `RealmQuery.distinct()`/`RealmQuery.distinctAsync()` instead. +* `RealmQuery.createQuery(Realm, Class)`, `RealmQuery.createDynamicQuery(DynamicRealm, String)`, `RealmQuery.createQueryFromResult(RealmResults)` and `RealmQuery.createQueryFromList(RealmList)` have been removed. Use `Realm.where(Class)`, `DynamicRealm.where(String)`, RealmResults.where()` and `RealmList.where()` instead. ### Internal From a3e24078cb265ec4d20d9bd1310e71a7217ca55b Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sun, 17 Sep 2017 05:27:50 +0900 Subject: [PATCH 55/72] remove unused code --- .../realm/ManagedRealmListForValueTests.java | 115 ++++++++---------- 1 file changed, 54 insertions(+), 61 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index 1b6da741d7..e6f9df93a2 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -72,30 +72,23 @@ public class ManagedRealmListForValueTests extends CollectionTests { static final int NULLABLE_TEST_SIZE = NON_NULL_TEST_SIZE * 2; enum ListType { - STRING_LIST(RealmFieldType.STRING_LIST, String.class.getName()), - BOOLEAN_LIST(RealmFieldType.BOOLEAN_LIST, Boolean.class.getName()), - BINARY_LIST(RealmFieldType.BINARY_LIST, byte[].class.getSimpleName()/* using simple name since array class is a bit special */), - LONG_LIST(RealmFieldType.INTEGER_LIST, Long.class.getName()), - INTEGER_LIST(RealmFieldType.INTEGER_LIST, Integer.class.getName()), - SHORT_LIST(RealmFieldType.INTEGER_LIST, Short.class.getName()), - BYTE_LIST(RealmFieldType.INTEGER_LIST, Byte.class.getName()), - DOUBLE_LIST(RealmFieldType.DOUBLE_LIST, Double.class.getName()), - FLOAT_LIST(RealmFieldType.FLOAT_LIST, Float.class.getName()), - DATE_LIST(RealmFieldType.DATE_LIST, Date.class.getName()); - - private final RealmFieldType fieldType; + STRING_LIST(String.class.getName()), + BOOLEAN_LIST(Boolean.class.getName()), + BINARY_LIST(byte[].class.getSimpleName()/* using simple name since array class is a bit special */), + LONG_LIST(Long.class.getName()), + INTEGER_LIST(Integer.class.getName()), + SHORT_LIST(Short.class.getName()), + BYTE_LIST(Byte.class.getName()), + DOUBLE_LIST(Double.class.getName()), + FLOAT_LIST(Float.class.getName()), + DATE_LIST(Date.class.getName()); + private final String valueTypeName; - ListType(RealmFieldType fieldType, String valueTypeName) { - this.fieldType = fieldType; + ListType(String valueTypeName) { this.valueTypeName = valueTypeName; } - @SuppressWarnings("unused") - public RealmFieldType getFieldType() { - return fieldType; - } - public String getValueTypeName() { return valueTypeName; } @@ -122,7 +115,7 @@ public static Collection parameters() { public ListType listType; @Parameterized.Parameter(1) - public Boolean typeIsNullable; + public Boolean isTypeNullable; private Realm realm; private NullTypes object; @@ -229,7 +222,7 @@ public void setUp() throws Exception { } realm.commitTransaction(); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); } static RealmList getListFor(NullTypes object, ListType listType, boolean nullable) { @@ -323,55 +316,55 @@ public void readValues() { for (int i = 0; i < NON_NULL_TEST_SIZE; i++) { switch (listType) { case STRING_LIST: { - assertEquals(generateValue(STRING_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(STRING_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; case BOOLEAN_LIST: { - assertEquals(generateValue(BOOLEAN_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(BOOLEAN_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; case BINARY_LIST: { - assertArrayEquals((byte[]) generateValue(BINARY_LIST, i), (byte[]) list.get(typeIsNullable ? (i * 2) : i)); + assertArrayEquals((byte[]) generateValue(BINARY_LIST, i), (byte[]) list.get(isTypeNullable ? (i * 2) : i)); } break; case LONG_LIST: { //noinspection UnnecessaryBoxing - assertEquals(generateValue(LONG_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(LONG_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; case INTEGER_LIST: { //noinspection UnnecessaryBoxing - assertEquals(generateValue(INTEGER_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(INTEGER_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; case SHORT_LIST: { //noinspection UnnecessaryBoxing - assertEquals(generateValue(SHORT_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(SHORT_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; case BYTE_LIST: { //noinspection UnnecessaryBoxing - assertEquals(generateValue(BYTE_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(BYTE_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; case DOUBLE_LIST: { //noinspection UnnecessaryBoxing - assertEquals(generateValue(DOUBLE_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(DOUBLE_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; case FLOAT_LIST: { //noinspection UnnecessaryBoxing - assertEquals(generateValue(FLOAT_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(FLOAT_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; case DATE_LIST: { - assertEquals(generateValue(DATE_LIST, i), list.get(typeIsNullable ? (i * 2) : i)); + assertEquals(generateValue(DATE_LIST, i), list.get(isTypeNullable ? (i * 2) : i)); } break; default: throw new AssertionError("unexpected value type: " + listType.name()); } - if (typeIsNullable) { + if (isTypeNullable) { assertNull(list.get(i * 2 + 1)); } } @@ -480,7 +473,7 @@ public void clear_then_add() { @Test public void size() { - assertEquals(typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE, list.size()); + assertEquals(isTypeNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE, list.size()); } @Test @@ -491,15 +484,15 @@ public void remove_nonNullByIndex() { @Override public void execute(Realm realm) { final Object removed = list.remove(targetIndex); - final int dataIndex = typeIsNullable ? targetIndex / 2 : targetIndex; + final int dataIndex = isTypeNullable ? targetIndex / 2 : targetIndex; assertValueEquals(generateValue(listType, dataIndex), removed); } }); - assertEquals(typeIsNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); + assertEquals(isTypeNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); for (int i = 0; i < list.size(); i++) { final int originalIndex = i < targetIndex ? i : i + 1; - if (typeIsNullable) { + if (isTypeNullable) { if (originalIndex % 2 == 1) { assertNull(list.get(i)); } else { @@ -513,7 +506,7 @@ public void execute(Realm realm) { @Test public void remove_nullByIndex() { - if (!typeIsNullable) { + if (!isTypeNullable) { return; } @@ -546,7 +539,7 @@ public void execute(Realm realm) { } }); - assertEquals((typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1, list.size()); + assertEquals((isTypeNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1, list.size()); } @Test @@ -554,8 +547,8 @@ public void remove_last() { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { - final Object removed = list.remove((typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1); - if (typeIsNullable) { + final Object removed = list.remove((isTypeNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1); + if (isTypeNullable) { assertNull(removed); } else { assertValueEquals(generateValue(listType, NON_NULL_TEST_SIZE - 1), removed); @@ -563,7 +556,7 @@ public void execute(Realm realm) { } }); - assertEquals((typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1, list.size()); + assertEquals((isTypeNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE) - 1, list.size()); } @Test @@ -600,7 +593,7 @@ public void remove_byNull() { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { - if (typeIsNullable) { + if (isTypeNullable) { assertTrue(list.remove(null)); } else { assertFalse(list.remove(null)); @@ -608,7 +601,7 @@ public void execute(Realm realm) { } }); - assertEquals(typeIsNullable ? (initialSize - 1) : initialSize, list.size()); + assertEquals(isTypeNullable ? (initialSize - 1) : initialSize, list.size()); } @Test @@ -620,10 +613,10 @@ public void execute(Realm realm) { } }); - assertEquals(typeIsNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); + assertEquals(isTypeNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); for (int i = 0; i < list.size(); i++) { final int originalIndex = i + 1; - if (typeIsNullable) { + if (isTypeNullable) { if (originalIndex % 2 == 1) { assertNull(list.get(i)); } else { @@ -644,9 +637,9 @@ public void execute(Realm realm) { } }); - assertEquals(typeIsNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); + assertEquals(isTypeNullable ? (NULLABLE_TEST_SIZE - 1) : (NON_NULL_TEST_SIZE - 1), list.size()); for (int i = 0; i < list.size(); i++) { - if (typeIsNullable) { + if (isTypeNullable) { if (i % 2 == 1) { assertNull(list.get(i)); } else { @@ -883,7 +876,7 @@ public void toString_() { sb.append(value); } sb.append(separator); - if (typeIsNullable) { + if (isTypeNullable) { sb.append("null").append(separator); } } @@ -961,7 +954,7 @@ public void deleteAllFromRealm_invalidListShouldThrow() { @Test public void add_null_nonNullableListThrows() { - if (typeIsNullable) { + if (isTypeNullable) { return; } @@ -978,7 +971,7 @@ public void add_null_nonNullableListThrows() { @Test public void addAt_null_nonNullableListThrows() { - if (typeIsNullable) { + if (isTypeNullable) { return; } @@ -995,7 +988,7 @@ public void addAt_null_nonNullableListThrows() { @Test public void set_null_nonNullableListThrows() { - if (typeIsNullable) { + if (isTypeNullable) { return; } @@ -1018,7 +1011,7 @@ public void changeListener_forAddObject() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); // add 3 elements as an initial data //noinspection unchecked @@ -1068,7 +1061,7 @@ public void changeListener_forAddAt() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); // add 3 elements as an initial data //noinspection unchecked @@ -1118,7 +1111,7 @@ public void changeListener_forSet() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); // add 3 elements as an initial data //noinspection unchecked @@ -1168,7 +1161,7 @@ public void changeListener_forRemoveAt() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); // add 3 elements as an initial data //noinspection unchecked @@ -1218,7 +1211,7 @@ public void changeListener_forRemoveObject() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); // add 3 elements as an initial data //noinspection unchecked @@ -1267,7 +1260,7 @@ public void changeListener_forRemoveAll() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); // add 3 elements as an initial data //noinspection unchecked @@ -1319,7 +1312,7 @@ public void changeListener_forDeleteAt() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); // add 3 elements as an initial data //noinspection unchecked @@ -1368,7 +1361,7 @@ public void changeListener_forDeleteAll() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); // add 3 elements as an initial data //noinspection unchecked @@ -1419,7 +1412,7 @@ public void removeAllChangeListeners() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); } }); @@ -1469,7 +1462,7 @@ public void removeChangeListener() { @Override public void execute(Realm realm) { object = realm.createObject(NullTypes.class, 1000); - list = getListFor(object, listType, typeIsNullable); + list = getListFor(object, listType, isTypeNullable); } }); From b7d01673d7f643f46b1c78782827b9426caaee99 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sun, 17 Sep 2017 05:41:03 +0900 Subject: [PATCH 56/72] update comment --- realm/realm-library/src/main/java/io/realm/RealmList.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index efbbef4014..4ab7f0843a 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -70,7 +70,7 @@ public class RealmList extends AbstractList implements OrderedRealmCollect @Nullable protected String className; - // Always null if RealmList is unmanaged, always non-null is managed. + // Always null if RealmList is unmanaged, always non-null if managed. private final ManagedListOperator osListOperator; final protected BaseRealm realm; private List unmanagedList; @@ -210,7 +210,6 @@ public void add(int location, @Nullable E element) { */ @Override public boolean add(@Nullable E object) { - //noinspection ConstantConditions if (isManaged()) { checkValidRealm(); //noinspection ConstantConditions From f27b2a2b263f6472695a48d6523a46d1f79b6cfb Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Sun, 17 Sep 2017 06:13:08 +0900 Subject: [PATCH 57/72] remove comment --- realm/realm-library/src/main/java/io/realm/RealmList.java | 1 - 1 file changed, 1 deletion(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 4ab7f0843a..c12c2b5715 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -212,7 +212,6 @@ public void add(int location, @Nullable E element) { public boolean add(@Nullable E object) { if (isManaged()) { checkValidRealm(); - //noinspection ConstantConditions osListOperator.add(object); } else { unmanagedList.add(object); From e9e960d4b83899d0f7c03b1e9b724ac98172bf14 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 21:04:38 +0900 Subject: [PATCH 58/72] update exception message --- CHANGELOG.md | 1 + realm/realm-library/src/main/java/io/realm/RealmList.java | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2400e9ebe8..f4df7d84e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * `RealmResults.distinct()`/`RealmResults.distinctAsync()` have been removed. Use `RealmQuery.distinct()`/`RealmQuery.distinctAsync()` instead. * `RealmQuery.createQuery(Realm, Class)`, `RealmQuery.createDynamicQuery(DynamicRealm, String)`, `RealmQuery.createQueryFromResult(RealmResults)` and `RealmQuery.createQueryFromList(RealmList)` have been removed. Use `Realm.where(Class)`, `DynamicRealm.where(String)`, RealmResults.where()` and `RealmList.where()` instead. +* Some exception messages are revised. ### Internal diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index c12c2b5715..15c6cc244f 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -60,9 +60,9 @@ public class RealmList extends AbstractList implements OrderedRealmCollection { - private static final String ONLY_IN_MANAGED_MODE_MESSAGE = "This method is only available in managed mode"; - private static final String ALLOWED_ONLY_FOR_REALM_MODEL_ELEMENT_MESSAGE = "This feature is available only when the element type is implementing RealmModel"; - public static final String REMOVE_OUTSIDE_TRANSACTION_ERROR = "Objects can only be removed from inside a write transaction"; + private static final String ONLY_IN_MANAGED_MODE_MESSAGE = "This method is only available in managed mode."; + private static final String ALLOWED_ONLY_FOR_REALM_MODEL_ELEMENT_MESSAGE = "This feature is available only when the element type is implementing RealmModel."; + public static final String REMOVE_OUTSIDE_TRANSACTION_ERROR = "Objects can only be removed from inside a write transaction."; private final io.realm.internal.Collection collection; @Nullable From 4acc4a28f1ee3265c9386ba2b1f71a4e4ed74198 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 21:06:05 +0900 Subject: [PATCH 59/72] update thrown.expectMessage() to check exception message --- .../java/io/realm/ManagedRealmListForValueTests.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index e6f9df93a2..64f7f798fc 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -53,6 +53,7 @@ import static io.realm.ManagedRealmListForValueTests.ListType.SHORT_LIST; import static io.realm.ManagedRealmListForValueTests.ListType.STRING_LIST; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -944,12 +945,9 @@ public void deleteAllFromRealm_invalidListShouldThrow() { realm.close(); realm = null; - try { - list.deleteAllFromRealm(); - fail("dogs is invalid and it should throw an exception"); - } catch (IllegalStateException e) { - assertEquals("This Realm instance has already been closed, making it unusable.", e.getMessage()); - } + thrown.expect(IllegalStateException.class); + thrown.expectMessage(is("This Realm instance has already been closed, making it unusable.")); + list.deleteAllFromRealm(); } @Test From 676a11b4dda9129dabf4a753caf2439ba71a66bd Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 21:19:52 +0900 Subject: [PATCH 60/72] fix test case name --- .../java/io/realm/ManagedRealmListForValueTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index 64f7f798fc..2f33cf1e94 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -653,7 +653,7 @@ public void execute(Realm realm) { } @Test - public void add_atAfterContainerObjectRemoved() { + public void addAt_afterContainerObjectRemoved() { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { From b33bb8e8d04aa7a7dce7fe77e60c70650bb3e6af Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 21:20:03 +0900 Subject: [PATCH 61/72] add assertion for remove/removeAll --- .../java/io/realm/ManagedRealmListForValueTests.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index 2f33cf1e94..11205b54f3 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -745,7 +745,7 @@ public void remove_unsupportedTypeIgnored() { public void execute(Realm realm) { for (Object unsupportedValue : unsupportedValues) { //noinspection UseBulkOperation - list.remove(unsupportedValue); + assertFalse(list.remove(unsupportedValue)); } } }); @@ -763,7 +763,7 @@ public void removeAll() { @Override public void execute(Realm realm) { //noinspection unchecked - list.removeAll(toBeRemoved); + assertTrue(list.removeAll(toBeRemoved)); } }); @@ -786,7 +786,7 @@ public void removeAll_unsupportedTypeIgnored() { @Override public void execute(Realm realm) { //noinspection unchecked - list.removeAll(unsupportedValues); + assertFalse(list.removeAll(unsupportedValues)); } }); @@ -1193,7 +1193,7 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch realm.beginTransaction(); //noinspection unchecked - list.remove(1); + assertEquals(generateValue(listType, 100), list.remove(1)); realm.commitTransaction(); assertEquals(2, listenerCalledCount.get()); @@ -1243,7 +1243,7 @@ public void onChange(RealmList element) { realm.beginTransaction(); //noinspection unchecked - list.remove(generateValue(listType, 100)); + assertTrue(list.remove(generateValue(listType, 100))); realm.commitTransaction(); assertEquals(2, listenerCalledCount.get()); @@ -1294,7 +1294,7 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch realm.beginTransaction(); //noinspection unchecked - list.removeAll(Arrays.asList(generateValue(listType, 100), generateValue(listType, 200), generateValue(listType, 300))); + assertTrue(list.removeAll(Arrays.asList(generateValue(listType, 100), generateValue(listType, 200), generateValue(listType, 300)))); realm.commitTransaction(); assertEquals(2, listenerCalledCount.get()); From b7b59bdf7174501e5715ee59860895809783668f Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 21:33:18 +0900 Subject: [PATCH 62/72] update RealmList.toString() --- .../src/main/java/io/realm/RealmList.java | 67 +++++++++++-------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 15c6cc244f..0327410c22 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -30,11 +30,11 @@ import java.util.Locale; import java.util.NoSuchElementException; -import io.reactivex.Flowable; -import io.reactivex.Observable; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import io.reactivex.Flowable; +import io.reactivex.Observable; import io.realm.internal.InvalidRow; import io.realm.internal.OsList; import io.realm.internal.RealmObjectProxy; @@ -849,8 +849,38 @@ public OrderedRealmCollectionSnapshot createSnapshot() { @Override public String toString() { - final StringBuilder sb = new StringBuilder("RealmList<"); - if (isManaged()) { + final String separator = ","; + final StringBuilder sb = new StringBuilder(); + + if (!isManaged()) { + // Build String for unmanaged RealmList + + // Unmanaged RealmList does not know actual element type. + sb.append("RealmList@["); + // Print list values + final int size = size(); + for (int i = 0; i < size; i++) { + final E value = get(i); + if (value instanceof RealmModel) { + sb.append(System.identityHashCode(value)); + } else { + if (value instanceof byte[]) { + sb.append("byte[").append(((byte[]) value).length).append("]"); + } else { + sb.append(value); + } + } + sb.append(separator); + } + if (0 < size()) { + sb.setLength(sb.length() - separator.length()); + } + sb.append("]"); + } else { + // Build String for managed RealmList + + // Determines type of List + sb.append("RealmList<"); if (className != null) { sb.append(className); } else { @@ -867,13 +897,9 @@ public String toString() { } } } - } else { - // unmanaged RealmList does not know actual element type. - sb.append("?"); - } - sb.append(">@["); - final String separator = ","; - if (isManaged()) { + sb.append(">@["); + + //Print list values if (!isAttached()) { sb.append("invalid"); } else if (isClassForRealmModel(clazz)) { @@ -899,25 +925,8 @@ public String toString() { sb.setLength(sb.length() - separator.length()); } } - } else { - for (int i = 0; i < size(); i++) { - final E value = get(i); - if (value instanceof RealmModel) { - sb.append(System.identityHashCode(value)); - } else { - if (value instanceof byte[]) { - sb.append("byte[").append(((byte[]) value).length).append("]"); - } else { - sb.append(value); - } - } - sb.append(separator); - } - if (0 < size()) { - sb.setLength(sb.length() - separator.length()); - } + sb.append("]"); } - sb.append("]"); return sb.toString(); } From a12c0c391660088ae9934202dbc0ed8effe88e06 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 21:36:01 +0900 Subject: [PATCH 63/72] update exception message --- realm/realm-library/src/main/java/io/realm/RealmList.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 0327410c22..7f9c1daa8a 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -1549,8 +1549,8 @@ private ManagedListOperator getOperator(BaseRealm realm, OsList osList, @Null } abstract class ManagedListOperator { - static final String NULL_OBJECTS_NOT_ALLOWED_MESSAGE = "RealmList does not accept null values"; - static final String INVALID_OBJECT_TYPE_MESSAGE = "Unacceptable value type. Acceptable: %1$s, actual: %2$s"; + static final String NULL_OBJECTS_NOT_ALLOWED_MESSAGE = "RealmList does not accept null values."; + static final String INVALID_OBJECT_TYPE_MESSAGE = "Unacceptable value type. Acceptable: %1$s, actual: %2$s ."; final BaseRealm realm; final OsList osList; From 88ed4bac9bd0aa9392a0959dfb337fdaab63df5b Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 21:42:58 +0900 Subject: [PATCH 64/72] fix failing tests --- .../java/io/realm/RealmListTests.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java index d625dac44b..19167e3aa8 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java @@ -141,9 +141,11 @@ public void add_unmanagedMode() { assertEquals(object, list.get(0)); } - @Test (expected = IllegalArgumentException.class) + @Test public void add_nullInUnmanagedMode() { - new RealmList().add(null); + final RealmList list = new RealmList<>(); + assertTrue(list.add(null)); + assertEquals(1, list.size()); } @Test @@ -189,9 +191,11 @@ public void add_objectAtIndexInManagedMode() { assertEquals("Dog 42", collection.get(0).getName()); } - @Test (expected = IllegalArgumentException.class) + @Test public void add_nullAtIndexInUnmanagedMode() { - new RealmList().add(0, null); + final RealmList list = new RealmList<>(); + list.add(0, null); + assertEquals(1, list.size()); } @Test @@ -223,11 +227,9 @@ public void set_managedMode() { @Test public void set_nullInUnmanagedMode() { - @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - RealmList list = new RealmList(); + RealmList list = new RealmList<>(); list.add(new AllTypes()); - thrown.expect(IllegalArgumentException.class); - list.set(0, null); + assertNotNull(list.set(0, null)); } @Test From 06d562db78c7c1a3a2e9f69d444870846cdf9d8f Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 22:26:53 +0900 Subject: [PATCH 65/72] remove special handling to byte array in RealmList --- .../realm/ManagedRealmListForValueTests.java | 44 +++++++--- .../src/main/java/io/realm/RealmList.java | 82 +------------------ 2 files changed, 37 insertions(+), 89 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index 11205b54f3..f2da8d0cda 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -580,11 +580,15 @@ public void remove_byObject() { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { - assertTrue(list.remove(value)); + if (listType == BINARY_LIST) { + assertFalse(list.remove(value)); // since 'equals()' never return true against binary array. + } else { + assertTrue(list.remove(value)); + } } }); - assertEquals(initialSize - 1, list.size()); + assertEquals((listType == BINARY_LIST) ? initialSize : (initialSize - 1), list.size()); } @Test @@ -762,15 +766,26 @@ public void removeAll() { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { - //noinspection unchecked - assertTrue(list.removeAll(toBeRemoved)); + if (!isTypeNullable && listType == BINARY_LIST) { + //noinspection unchecked + assertFalse(list.removeAll(toBeRemoved)); // since 'equals()' never return true against binary array. + } else { + //noinspection unchecked + assertTrue(list.removeAll(toBeRemoved)); + } } }); - if (listType == BOOLEAN_LIST) { - assertEquals(NON_NULL_TEST_SIZE / 2, list.size()); - } else { - assertEquals(NON_NULL_TEST_SIZE - 2, list.size()); + switch (listType) { + case BINARY_LIST: + assertEquals(NON_NULL_TEST_SIZE, list.size()); + break; + case BOOLEAN_LIST: + assertEquals(NON_NULL_TEST_SIZE / 2, list.size()); + break; + default: + assertEquals(NON_NULL_TEST_SIZE - 2, list.size()); + break; } } @@ -1232,7 +1247,8 @@ public void onChange(RealmList element) { //noinspection unchecked list.addChangeListener(new OrderedRealmCollectionChangeListener>() { @Override - public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { assertEquals(1, changes.getInsertions().length); + public void onChange(RealmList collection, OrderedCollectionChangeSet changes) { + assertEquals(1, changes.getInsertions().length); assertEquals(0, changes.getInsertions().length); assertEquals(1, changes.getDeletions().length); assertEquals(0, changes.getChanges().length); @@ -1253,6 +1269,12 @@ public void onChange(RealmList element) { @Test @RunTestInLooperThread public void changeListener_forRemoveAll() { + if (listType == BINARY_LIST) { + // 'removeAll()' never remove byte array element since 'equals()' never return true against byte array. + looperThread.testComplete(); + return; + } + Realm realm = looperThread.getRealm(); realm.executeTransaction(new Realm.Transaction() { @Override @@ -1294,7 +1316,9 @@ public void onChange(RealmList collection, OrderedCollectionChangeSet ch realm.beginTransaction(); //noinspection unchecked - assertTrue(list.removeAll(Arrays.asList(generateValue(listType, 100), generateValue(listType, 200), generateValue(listType, 300)))); + + final boolean removed = list.removeAll(Arrays.asList(generateValue(listType, 100), generateValue(listType, 200), generateValue(listType, 300))); + assertTrue(removed); realm.commitTransaction(); assertEquals(2, listenerCalledCount.get()); diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 7f9c1daa8a..c7a1c14ee2 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -19,7 +19,6 @@ import java.lang.reflect.Array; import java.util.AbstractList; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.ConcurrentModificationException; @@ -343,26 +342,9 @@ public boolean remove(@Nullable Object object) { if (isManaged() && !realm.isInTransaction()) { throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR); } - - if (object instanceof byte[] && clazz == byte[].class) { - // we need special handling for class since equals against byte[] never matches. - return remove((byte[]) object); - } return super.remove(object); } - private boolean remove(@Nonnull byte[] value) { - Iterator it = iterator(); - while (it.hasNext()) { - final E e = it.next(); - if (e instanceof byte[] && Arrays.equals(value, (byte[]) e)) { - it.remove(); - return true; - } - } - return false; - } - /** * Removes all occurrences in this {@code Collection} of each object in the * specified {@code Collection}. After this method returns none of the @@ -384,29 +366,7 @@ public boolean removeAll(Collection collection) { if (isManaged() && !realm.isInTransaction()) { throw new IllegalStateException(REMOVE_OUTSIDE_TRANSACTION_ERROR); } - - boolean modified = false; - Iterator it = iterator(); - while (it.hasNext()) { - final Object element = it.next(); - if (element instanceof byte[]) { - final byte[] bytesElement = (byte[]) element; - // we can't use collection.contains() since equals() of byte[] never be true - for (Object a : collection) { - if (a instanceof byte[] && Arrays.equals(bytesElement, (byte[]) a)) { - it.remove(); - modified = true; - break; - } - } - } else { - if (collection.contains(element)) { - it.remove(); - modified = true; - } - } - } - return modified; + return super.removeAll(collection); } /** @@ -742,45 +702,9 @@ public boolean contains(@Nullable Object object) { } } - if (object == null) { - for (E e : this) { - if (e == null) { - return true; - } - } - return false; - } else { - if (object instanceof byte[] && clazz == byte[].class) { - // byte[] requires special handling - final byte[] bytesObject = (byte[]) object; - for (E e : this) { - if (Arrays.equals((byte[]) e, bytesObject)) { - return true; - } - } - return false; - } else { - for (E e : this) { - if (e != null && e.equals(object)) { - return true; - } - } - return false; - } - } + return super.contains(object); } else { - if (object instanceof byte[]) { - // byte[] requires special handling - final byte[] bytesObject = (byte[]) object; - for (E e : this) { - if (e instanceof byte[] && Arrays.equals((byte[]) e, bytesObject)) { - return true; - } - } - return false; - } else { - return unmanagedList.contains(object); - } + return unmanagedList.contains(object); } } From 40b1ac277233a3bf9c9c7b658e10bed70be06aeb Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 22:50:08 +0900 Subject: [PATCH 66/72] remove special type conversion via Number in toArray() --- ...ManagedRealmListForValue_toArrayTests.java | 58 +---- .../src/main/java/io/realm/RealmList.java | 210 ------------------ 2 files changed, 11 insertions(+), 257 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java index aea0079673..1d7dc8b403 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValue_toArrayTests.java @@ -25,13 +25,9 @@ import org.junit.runners.Parameterized; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Date; -import java.util.HashSet; import java.util.List; -import java.util.Set; import io.realm.ManagedRealmListForValueTests.ListType; import io.realm.entities.NullTypes; @@ -201,18 +197,6 @@ public void tearDown() throws Exception { } } - private static final Set NON_NUMBER_LIST_TYPES; - - static { - final HashSet set = new HashSet<>(); - set.add(STRING_LIST); - set.add(BOOLEAN_LIST); - set.add(BINARY_LIST); - set.add(DATE_LIST); - - NON_NUMBER_LIST_TYPES = Collections.unmodifiableSet(set); - } - @Test public void toArray() { final Object[] expected = new Object[typeIsNullable ? NULLABLE_TEST_SIZE : NON_NULL_TEST_SIZE]; @@ -243,9 +227,7 @@ public void toArray() { @Test public void toArray_withStringArray() { - final boolean exceptionExpected = (listType != STRING_LIST); - - if (exceptionExpected) { + if (listType != STRING_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new String[0]); // should not reach here @@ -268,9 +250,7 @@ public void toArray_withStringArray() { @Test public void toArray_withBooleanArray() { - final boolean exceptionExpected = (listType != BOOLEAN_LIST); - - if (exceptionExpected) { + if (listType != BOOLEAN_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new Boolean[0]); // should not reach here @@ -294,9 +274,7 @@ public void toArray_withBooleanArray() { @Test public void toArray_withBinaryArray() { - final boolean exceptionExpected = (listType != BINARY_LIST); - - if (exceptionExpected) { + if (listType != BINARY_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new byte[0][]); // should not reach here @@ -328,9 +306,7 @@ public void toArray_withBinaryArray() { @Test public void toArray_withLongArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { + if (listType != LONG_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new Long[0]); // should not reach here @@ -353,9 +329,7 @@ public void toArray_withLongArray() { @Test public void toArray_withIntegerArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { + if (listType != INTEGER_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new Integer[0]); // should not reach here @@ -378,9 +352,7 @@ public void toArray_withIntegerArray() { @Test public void toArray_withShortArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { + if (listType != SHORT_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new Short[0]); // should not reach here @@ -403,9 +375,7 @@ public void toArray_withShortArray() { @Test public void toArray_withByteArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { + if (listType != BYTE_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new Byte[0]); // should not reach here @@ -428,9 +398,7 @@ public void toArray_withByteArray() { @Test public void toArray_withDoubleArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { + if (listType != DOUBLE_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new Double[0]); // should not reach here @@ -453,9 +421,7 @@ public void toArray_withDoubleArray() { @Test public void toArray_withFloatArray() { - final boolean exceptionExpected = NON_NUMBER_LIST_TYPES.contains(listType); - - if (exceptionExpected) { + if (listType != FLOAT_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new Float[0]); // should not reach here @@ -478,9 +444,7 @@ public void toArray_withFloatArray() { @Test public void toArray_withDateArray() { - final boolean exceptionExpected = (listType != DATE_LIST); - - if (exceptionExpected) { + if (listType != DATE_LIST) { thrown.expect(ArrayStoreException.class); list.toArray(new Date[0]); // should not reach here @@ -500,4 +464,4 @@ public void toArray_withDateArray() { assertEquals(Date.class, returnedArray.getClass().getComponentType()); assertArrayEquals(expected, returnedArray); } -} \ No newline at end of file +} diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index c7a1c14ee2..94e070470d 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -1223,216 +1223,6 @@ public void add(@Nullable E e) { } } - @Override - public T[] toArray(T[] a) { - if (!isManaged()) { - return super.toArray(a); - } - - final Class componentType = a.getClass().getComponentType(); - final int size = size(); - if (componentType == String.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - for (int i = 0; i < size; i++) { - //noinspection unchecked - a[i] = (T) osListOperator.get(i); - } - return a; - } - - if (componentType == Long.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - if (e == null || e instanceof Long) { - //noinspection unchecked - a[i] = (T) e; - } else { - if (!(e instanceof Number)) { - throw new ArrayStoreException(String.format(Locale.ENGLISH, - "The element of type %1$s can't be stored into the array of %2$s", - e.getClass().getName(), a.getClass().getComponentType())); - } - //noinspection unchecked - a[i] = (T) Long.valueOf(((Number) e).longValue()); - } - } - return a; - } - - if (componentType == Integer.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - - if (e == null || e instanceof Integer) { - //noinspection unchecked - a[i] = (T) e; - } else { - if (!(e instanceof Number)) { - throw new ArrayStoreException(String.format(Locale.ENGLISH, - "The element of type %1$s can't be stored into the array of %2$s", - e.getClass().getName(), a.getClass().getComponentType())); - } - //noinspection unchecked - a[i] = (T) Integer.valueOf(((Number) e).intValue()); - } - } - return a; - } - - if (componentType == Short.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - if (e == null || e instanceof Short) { - //noinspection unchecked - a[i] = (T) e; - } else { - if (!(e instanceof Number)) { - throw new ArrayStoreException(String.format(Locale.ENGLISH, - "The element of type %1$s can't be stored into the array of %2$s", - e.getClass().getName(), a.getClass().getComponentType())); - } - //noinspection unchecked - a[i] = (T) Short.valueOf(((Number) e).shortValue()); - } - } - return a; - } - - if (componentType == Byte.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - if (e == null || e instanceof Byte) { - //noinspection unchecked - a[i] = (T) e; - } else { - if (!(e instanceof Number)) { - throw new ArrayStoreException(String.format(Locale.ENGLISH, - "The element of type %1$s can't be stored into the array of %2$s", - e.getClass().getName(), a.getClass().getComponentType())); - } - //noinspection unchecked - a[i] = (T) Byte.valueOf(((Number) e).byteValue()); - } - } - return a; - } - - if (componentType == Double.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - if (e == null || e instanceof Double) { - //noinspection unchecked - a[i] = (T) e; - } else { - if (!(e instanceof Number)) { - throw new ArrayStoreException(String.format(Locale.ENGLISH, - "The element of type %1$s can't be stored into the array of %2$s", - e.getClass().getName(), a.getClass().getComponentType())); - } - //noinspection unchecked - a[i] = (T) Double.valueOf(((Number) e).doubleValue()); - } - } - return a; - } - - if (componentType == Float.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - if (e == null || e instanceof Float) { - //noinspection unchecked - a[i] = (T) e; - } else { - if (!(e instanceof Number)) { - throw new ArrayStoreException(String.format(Locale.ENGLISH, - "The element of type %1$s can't be stored into the array of %2$s", - e.getClass().getName(), a.getClass().getComponentType())); - } - //noinspection unchecked - a[i] = (T) Float.valueOf(((Number) e).floatValue()); - } - } - return a; - } - - if (componentType == Boolean.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - //noinspection unchecked - a[i] = (T) e; - } - return a; - } - - if (componentType == Date.class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - //noinspection unchecked - a[i] = (T) e; - } - return a; - } - - if (componentType == byte[].class) { - if (a.length < size) { - //noinspection unchecked - a = (T[]) Array.newInstance(componentType, size); - } - - for (int i = 0; i < size; i++) { - final E e = osListOperator.get(i); - //noinspection unchecked - a[i] = (T) e; - } - return a; - } - - return super.toArray(a); - } - private static boolean isClassForRealmModel(Class clazz) { return RealmModel.class.isAssignableFrom(clazz); } From 4ff447da97e8135826615af349187ca055068b2e Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Mon, 18 Sep 2017 23:30:37 +0900 Subject: [PATCH 67/72] fix failing tests --- .../java/io/realm/ManagedRealmListForValueTests.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index 11cf9fdabd..51fbb2dd52 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -1209,7 +1209,11 @@ public void onChange(RealmList collection, @Nullable OrderedCollectionCh realm.beginTransaction(); //noinspection unchecked - assertEquals(generateValue(listType, 100), list.remove(1)); + if (listType == BINARY_LIST) { + assertArrayEquals((byte[]) generateValue(listType, 100), (byte[]) list.remove(1)); + } else { + assertEquals(generateValue(listType, 100), list.remove(1)); + } realm.commitTransaction(); assertEquals(2, listenerCalledCount.get()); @@ -1219,6 +1223,12 @@ public void onChange(RealmList collection, @Nullable OrderedCollectionCh @Test @RunTestInLooperThread public void changeListener_forRemoveObject() { + if (listType == BINARY_LIST) { + // 'removeAll()' never remove byte array element since 'equals()' never return true against byte array. + looperThread.testComplete(); + return; + } + Realm realm = looperThread.getRealm(); realm.executeTransaction(new Realm.Transaction() { @Override From 90affd156404b5668c555d38d0ca8a5db8523b6b Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 19 Sep 2017 00:37:43 +0900 Subject: [PATCH 68/72] remove unnecessary index checks --- .../realm/ManagedRealmListForValueTests.java | 28 ++++++++++++++++++ .../java/io/realm/RealmListTests.java | 14 +++++++++ .../src/main/java/io/realm/RealmList.java | 29 +++---------------- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index f2da8d0cda..9d2c12f4bc 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -670,6 +670,20 @@ public void execute(Realm realm) { list.add(generateValue(listType, 100)); } + @Test + public void addAt_invalidIndex() { + final int initialSize = list.size(); + try { + realm.beginTransaction(); + //noinspection unchecked + list.add(initialSize + 1, generateValue(listType, 1000)); + fail(); + } catch (IndexOutOfBoundsException e) { + // make sure that the size is not changed + assertEquals(initialSize, list.size()); + } + } + @Test public void set_afterContainerObjectRemoved() { realm.executeTransaction(new Realm.Transaction() { @@ -684,6 +698,20 @@ public void execute(Realm realm) { list.set(0, generateValue(listType, 100)); } + @Test + public void set_invalidIndex() { + final int initialSize = list.size(); + try { + realm.beginTransaction(); + //noinspection unchecked + list.set(initialSize, generateValue(listType, 1000)); + fail(); + } catch (IndexOutOfBoundsException e) { + // make sure that the size is not changed + assertEquals(initialSize, list.size()); + } + } + @Test public void move_afterContainerObjectRemoved() { realm.executeTransaction(new Realm.Transaction() { diff --git a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java index 19167e3aa8..6547300fed 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/RealmListTests.java @@ -191,6 +191,20 @@ public void add_objectAtIndexInManagedMode() { assertEquals("Dog 42", collection.get(0).getName()); } + @Test + public void add_objectAtInvalidIndexInManagedModeThrows() { + final int initialDogCount = realm.where(Dog.class).findAll().size(); + + realm.beginTransaction(); + try { + final int invalidIndex = collection.size() + 1; + collection.add(invalidIndex, new Dog("Dog 42")); + fail(); + } catch (IndexOutOfBoundsException e) { + assertEquals(initialDogCount, realm.where(Dog.class).findAll().size()); + } + } + @Test public void add_nullAtIndexInUnmanagedMode() { final RealmList list = new RealmList<>(); diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 94e070470d..f4f63bca5e 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -16,7 +16,6 @@ package io.realm; -import java.lang.reflect.Array; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; @@ -39,6 +38,7 @@ import io.realm.internal.RealmObjectProxy; import io.realm.rx.CollectionChange; + /** * RealmList is used to model one-to-many relationships in a {@link io.realm.RealmObject}. * RealmList has two modes: A managed and unmanaged mode. In managed mode all objects are persisted inside a Realm, in @@ -900,7 +900,7 @@ public Flowable> asFlowable() { *

* RealmList will continually be emitted as the RealmList is updated - {@code onComplete} will never be called. *

- * * Note that when the {@link Realm} is accessed from threads other than where it was created, + * * Note that when the {@link Realm} is accessed from threads other than where it was created, * {@link IllegalStateException} will be thrown. Care should be taken when using different schedulers * with {@code subscribeOn()} and {@code observeOn()}. Consider using {@code Realm.where().find*Async()} * instead. @@ -1303,13 +1303,6 @@ final void checkInsertIndex(int index) { } } - final void checkElementExists(int index) { - final int size = size(); - if (index < 0 || size <= index) { - throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); - } - } - @Nullable abstract T get(int index); @@ -1390,6 +1383,7 @@ public void add(@Nullable Object value) { @Override public void insert(int index, @Nullable Object value) { final RealmModel model = castToNonNullModel(value); + // need to check in advance to avoid unnecessary copy of unmanaged object into Realm. checkInsertIndex(index); RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); @@ -1399,11 +1393,10 @@ public void insert(int index, @Nullable Object value) { @Override protected T set(int index, @Nullable Object value) { final RealmModel model = castToNonNullModel(value); - checkElementExists(index); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); //noinspection unchecked final T oldObject = get(index); + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); osList.setRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); return oldObject; } @@ -1500,7 +1493,6 @@ public void add(@Nullable Object value) { @Override public void insert(int index, @Nullable Object value) { checkValidValue(value); - checkInsertIndex(index); if (value == null) { osList.insertNull(index); @@ -1513,7 +1505,6 @@ public void insert(int index, @Nullable Object value) { @Nullable protected String set(int index, @Nullable Object value) { checkValidValue(value); - checkElementExists(index); final String oldValue = get(index); if (value == null) { @@ -1589,7 +1580,6 @@ public void add(@Nullable Object value) { @Override public void insert(int index, @Nullable Object value) { checkValidValue(value); - checkInsertIndex(index); if (value == null) { osList.insertNull(index); @@ -1602,7 +1592,6 @@ public void insert(int index, @Nullable Object value) { @Override protected T set(int index, @Nullable Object value) { checkValidValue(value); - checkElementExists(index); final T oldValue = get(index); if (value == null) { @@ -1657,7 +1646,6 @@ public void add(@Nullable Object value) { @Override public void insert(int index, @Nullable Object value) { checkValidValue(value); - checkInsertIndex(index); if (value == null) { osList.insertNull(index); @@ -1670,7 +1658,6 @@ public void insert(int index, @Nullable Object value) { @Override protected Boolean set(int index, @Nullable Object value) { checkValidValue(value); - checkElementExists(index); final Boolean oldValue = get(index); if (value == null) { @@ -1725,7 +1712,6 @@ public void add(@Nullable Object value) { @Override public void insert(int index, @Nullable Object value) { checkValidValue(value); - checkInsertIndex(index); if (value == null) { osList.insertNull(index); @@ -1738,7 +1724,6 @@ public void insert(int index, @Nullable Object value) { @Override protected byte[] set(int index, @Nullable Object value) { checkValidValue(value); - checkElementExists(index); final byte[] oldValue = get(index); if (value == null) { @@ -1793,7 +1778,6 @@ public void add(@Nullable Object value) { @Override public void insert(int index, @Nullable Object value) { checkValidValue(value); - checkInsertIndex(index); if (value == null) { osList.insertNull(index); @@ -1806,7 +1790,6 @@ public void insert(int index, @Nullable Object value) { @Override protected Double set(int index, @Nullable Object value) { checkValidValue(value); - checkElementExists(index); final Double oldValue = get(index); if (value == null) { @@ -1861,7 +1844,6 @@ public void add(@Nullable Object value) { @Override public void insert(int index, @Nullable Object value) { checkValidValue(value); - checkInsertIndex(index); if (value == null) { osList.insertNull(index); @@ -1874,7 +1856,6 @@ public void insert(int index, @Nullable Object value) { @Override protected Float set(int index, @Nullable Object value) { checkValidValue(value); - checkElementExists(index); final Float oldValue = get(index); if (value == null) { @@ -1929,7 +1910,6 @@ public void add(@Nullable Object value) { @Override public void insert(int index, @Nullable Object value) { checkValidValue(value); - checkInsertIndex(index); if (value == null) { osList.insertNull(index); @@ -1942,7 +1922,6 @@ public void insert(int index, @Nullable Object value) { @Override protected Date set(int index, @Nullable Object value) { checkValidValue(value); - checkElementExists(index); final Date oldValue = get(index); if (value == null) { From 38bd2bcb03460162e344a4780d07bb861573d4f4 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 19 Sep 2017 12:40:26 +0900 Subject: [PATCH 69/72] refactor ManagedListOperator and its sub-classes --- .../src/main/java/io/realm/RealmList.java | 388 +++++++----------- 1 file changed, 153 insertions(+), 235 deletions(-) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index f4f63bca5e..28bc18c352 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -211,7 +211,7 @@ public void add(int location, @Nullable E element) { public boolean add(@Nullable E object) { if (isManaged()) { checkValidRealm(); - osListOperator.add(object); + osListOperator.append(object); } else { unmanagedList.add(object); } @@ -1277,41 +1277,82 @@ abstract class ManagedListOperator { this.osList = osList; } - abstract boolean forRealmModel(); + public abstract boolean forRealmModel(); - OsList getOsList() { + public final OsList getOsList() { return osList; } - final boolean isValid() { + public final boolean isValid() { return osList.isValid(); } - final int size() { + public final int size() { final long actualSize = osList.size(); return actualSize < Integer.MAX_VALUE ? (int) actualSize : Integer.MAX_VALUE; } - final boolean isEmpty() { + public final boolean isEmpty() { return osList.isEmpty(); } - final void checkInsertIndex(int index) { - final int size = size(); - if (index < 0 || size < index) { - throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); + protected abstract void checkValidValue(@Nullable Object value); + + @Nullable + public abstract T get(int index); + + public final void append(@Nullable Object value) { + checkValidValue(value); + + if (value == null) { + appendNull(); + } else { + appendValue(value); } } - @Nullable - abstract T get(int index); + private void appendNull() { + osList.addNull(); + } + + abstract protected void appendValue(Object value); + + public final void insert(int index, @Nullable Object value) { + checkValidValue(value); - abstract void add(@Nullable Object value); + if (value == null) { + insertNull(index); + } else { + insertValue(index, value); + } - abstract void insert(int index, @Nullable Object value); + } + + protected void insertNull(int index) { + osList.insertNull(index); + } + + protected abstract void insertValue(int index, Object value); @Nullable - abstract T set(int index, @Nullable Object value); + public final T set(int index, @Nullable Object value) { + checkValidValue(value); + + //noinspection unchecked + final T oldObject = get(index); + if (value == null) { + setNull(index); + } else { + setValue(index, value); + } + return oldObject; + } + + protected void setNull(int index) { + osList.setNull(index); + } + + abstract protected void setValue(int index, Object value); final void move(int oldPos, int newPos) { osList.move(oldPos, newPos); @@ -1336,6 +1377,7 @@ final void deleteLast() { final void deleteAll() { osList.deleteAll(); } + } final class RealmModelListOperator extends ManagedListOperator { @@ -1349,18 +1391,18 @@ final class RealmModelListOperator extends ManagedListOperator { } @Override - boolean forRealmModel() { + public boolean forRealmModel() { return true; } @Override - T get(int index) { + public T get(int index) { //noinspection unchecked return (T) realm.get((Class) clazz, className, osList.getUncheckedRow(index)); } - @Nonnull - private RealmModel castToNonNullModel(@Nullable Object value) { + @Override + protected void checkValidValue(@Nullable Object value) { if (value == null) { throw new IllegalArgumentException(NULL_OBJECTS_NOT_ALLOWED_MESSAGE); } @@ -1370,35 +1412,44 @@ private RealmModel castToNonNullModel(@Nullable Object value) { "java.lang.String", value.getClass().getName())); } - return (RealmModel) value; + } + + private void checkInsertIndex(int index) { + final int size = size(); + if (index < 0 || size < index) { + throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + osList.size()); + } } @Override - public void add(@Nullable Object value) { - final RealmModel model = castToNonNullModel(value); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); + public void appendValue(Object value) { + final RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); osList.addRow(proxy.realmGet$proxyState().getRow$realm().getIndex()); } @Override - public void insert(int index, @Nullable Object value) { - final RealmModel model = castToNonNullModel(value); + protected void insertNull(int index) { + throw new RuntimeException("Should not reach here."); + } + + @Override + public void insertValue(int index, Object value) { // need to check in advance to avoid unnecessary copy of unmanaged object into Realm. checkInsertIndex(index); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); osList.insertRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); } @Override - protected T set(int index, @Nullable Object value) { - final RealmModel model = castToNonNullModel(value); + protected void setNull(int index) { + throw new RuntimeException("Should not reach here."); + } - //noinspection unchecked - final T oldObject = get(index); - RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded(model); + @Override + protected void setValue(int index, Object value) { + RealmObjectProxy proxy = (RealmObjectProxy) copyToRealmIfNeeded((RealmModel) value); osList.setRow(index, proxy.realmGet$proxyState().getRow$realm().getIndex()); - return oldObject; } // Transparently copies an unmanaged object or managed object from another Realm to the Realm backing this RealmList. @@ -1457,17 +1508,18 @@ final class StringListOperator extends ManagedListOperator { } @Override - boolean forRealmModel() { + public boolean forRealmModel() { return false; } @Nullable @Override - String get(int index) { + public String get(int index) { return (String) osList.getValue(index); } - private void checkValidValue(@Nullable Object value) { + @Override + protected void checkValidValue(@Nullable Object value) { if (value == null) { // null is always valid (but schema may reject null on insertion). return; @@ -1481,38 +1533,18 @@ private void checkValidValue(@Nullable Object value) { } @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addString((String) value); - } + public void appendValue(Object value) { + osList.addString((String) value); } @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - - if (value == null) { - osList.insertNull(index); - } else { - osList.insertString(index, (String) value); - } + public void insertValue(int index, Object value) { + osList.insertString(index, (String) value); } @Override - @Nullable - protected String set(int index, @Nullable Object value) { - checkValidValue(value); - - final String oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setString(index, (String) value); - } - return oldValue; + protected void setValue(int index, Object value) { + osList.setString(index, (String) value); } } @@ -1523,13 +1555,13 @@ final class LongListOperator extends ManagedListOperator { } @Override - boolean forRealmModel() { + public boolean forRealmModel() { return false; } @Nullable @Override - T get(int index) { + public T get(int index) { final Long value = (Long) osList.getValue(index); if (value == null) { return null; @@ -1554,7 +1586,8 @@ T get(int index) { throw new IllegalStateException("Unexpected element type: " + clazz.getName()); } - private void checkValidValue(@Nullable Object value) { + @Override + protected void checkValidValue(@Nullable Object value) { if (value == null) { // null is always valid (but schema may reject null on insertion). return; @@ -1568,38 +1601,18 @@ private void checkValidValue(@Nullable Object value) { } @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addLong(((Number) value).longValue()); - } + public void appendValue(Object value) { + osList.addLong(((Number) value).longValue()); } @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - - if (value == null) { - osList.insertNull(index); - } else { - osList.insertLong(index, ((Number) value).longValue()); - } + public void insertValue(int index, Object value) { + osList.insertLong(index, ((Number) value).longValue()); } - @Nullable @Override - protected T set(int index, @Nullable Object value) { - checkValidValue(value); - - final T oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setLong(index, ((Number) value).longValue()); - } - return oldValue; + protected void setValue(int index, Object value) { + osList.setLong(index, ((Number) value).longValue()); } } @@ -1610,17 +1623,18 @@ final class BooleanListOperator extends ManagedListOperator { } @Override - boolean forRealmModel() { + public boolean forRealmModel() { return false; } @Nullable @Override - Boolean get(int index) { + public Boolean get(int index) { return (Boolean) osList.getValue(index); } - private void checkValidValue(@Nullable Object value) { + @Override + protected void checkValidValue(@Nullable Object value) { if (value == null) { // null is always valid (but schema may reject null on insertion). return; @@ -1634,38 +1648,18 @@ private void checkValidValue(@Nullable Object value) { } @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addBoolean((Boolean) value); - } + public void appendValue(Object value) { + osList.addBoolean((Boolean) value); } @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - - if (value == null) { - osList.insertNull(index); - } else { - osList.insertBoolean(index, (Boolean) value); - } + public void insertValue(int index, Object value) { + osList.insertBoolean(index, (Boolean) value); } - @Nullable @Override - protected Boolean set(int index, @Nullable Object value) { - checkValidValue(value); - - final Boolean oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setBoolean(index, (Boolean) value); - } - return oldValue; + protected void setValue(int index, Object value) { + osList.setBoolean(index, (Boolean) value); } } @@ -1676,17 +1670,18 @@ final class BinaryListOperator extends ManagedListOperator { } @Override - boolean forRealmModel() { + public boolean forRealmModel() { return false; } @Nullable @Override - byte[] get(int index) { + public byte[] get(int index) { return (byte[]) osList.getValue(index); } - private void checkValidValue(@Nullable Object value) { + @Override + protected void checkValidValue(@Nullable Object value) { if (value == null) { // null is always valid (but schema may reject null on insertion). return; @@ -1700,38 +1695,18 @@ private void checkValidValue(@Nullable Object value) { } @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addBinary((byte[]) value); - } + public void appendValue(Object value) { + osList.addBinary((byte[]) value); } @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - - if (value == null) { - osList.insertNull(index); - } else { - osList.insertBinary(index, (byte[]) value); - } + public void insertValue(int index, Object value) { + osList.insertBinary(index, (byte[]) value); } - @Nullable @Override - protected byte[] set(int index, @Nullable Object value) { - checkValidValue(value); - - final byte[] oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setBinary(index, (byte[]) value); - } - return oldValue; + protected void setValue(int index, Object value) { + osList.setBinary(index, (byte[]) value); } } @@ -1742,17 +1717,18 @@ final class DoubleListOperator extends ManagedListOperator { } @Override - boolean forRealmModel() { + public boolean forRealmModel() { return false; } @Nullable @Override - Double get(int index) { + public Double get(int index) { return (Double) osList.getValue(index); } - private void checkValidValue(@Nullable Object value) { + @Override + protected void checkValidValue(@Nullable Object value) { if (value == null) { // null is always valid (but schema may reject null on insertion). return; @@ -1766,38 +1742,18 @@ private void checkValidValue(@Nullable Object value) { } @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addDouble(((Number) value).doubleValue()); - } + public void appendValue(Object value) { + osList.addDouble(((Number) value).doubleValue()); } @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - - if (value == null) { - osList.insertNull(index); - } else { - osList.insertDouble(index, ((Number) value).doubleValue()); - } + public void insertValue(int index, Object value) { + osList.insertDouble(index, ((Number) value).doubleValue()); } - @Nullable @Override - protected Double set(int index, @Nullable Object value) { - checkValidValue(value); - - final Double oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setDouble(index, ((Number) value).doubleValue()); - } - return oldValue; + protected void setValue(int index, Object value) { + osList.setDouble(index, ((Number) value).doubleValue()); } } @@ -1808,17 +1764,18 @@ final class FloatListOperator extends ManagedListOperator { } @Override - boolean forRealmModel() { + public boolean forRealmModel() { return false; } @Nullable @Override - Float get(int index) { + public Float get(int index) { return (Float) osList.getValue(index); } - private void checkValidValue(@Nullable Object value) { + @Override + protected void checkValidValue(@Nullable Object value) { if (value == null) { // null is always valid (but schema may reject null on insertion). return; @@ -1832,38 +1789,18 @@ private void checkValidValue(@Nullable Object value) { } @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addFloat(((Number) value).floatValue()); - } + public void appendValue(Object value) { + osList.addFloat(((Number) value).floatValue()); } @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - - if (value == null) { - osList.insertNull(index); - } else { - osList.insertFloat(index, ((Number) value).floatValue()); - } + public void insertValue(int index, Object value) { + osList.insertFloat(index, ((Number) value).floatValue()); } - @Nullable @Override - protected Float set(int index, @Nullable Object value) { - checkValidValue(value); - - final Float oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setFloat(index, ((Number) value).floatValue()); - } - return oldValue; + protected void setValue(int index, Object value) { + osList.setFloat(index, ((Number) value).floatValue()); } } @@ -1874,17 +1811,18 @@ final class DateListOperator extends ManagedListOperator { } @Override - boolean forRealmModel() { + public boolean forRealmModel() { return false; } @Nullable @Override - Date get(int index) { + public Date get(int index) { return (Date) osList.getValue(index); } - private void checkValidValue(@Nullable Object value) { + @Override + protected void checkValidValue(@Nullable Object value) { if (value == null) { // null is always valid (but schema may reject null on insertion). return; @@ -1898,37 +1836,17 @@ private void checkValidValue(@Nullable Object value) { } @Override - public void add(@Nullable Object value) { - checkValidValue(value); - if (value == null) { - osList.addNull(); - } else { - osList.addDate((Date) value); - } + public void appendValue(Object value) { + osList.addDate((Date) value); } @Override - public void insert(int index, @Nullable Object value) { - checkValidValue(value); - - if (value == null) { - osList.insertNull(index); - } else { - osList.insertDate(index, (Date) value); - } + public void insertValue(int index, Object value) { + osList.insertDate(index, (Date) value); } - @Nullable @Override - protected Date set(int index, @Nullable Object value) { - checkValidValue(value); - - final Date oldValue = get(index); - if (value == null) { - osList.setNull(index); - } else { - osList.setDate(index, (Date) value); - } - return oldValue; + protected void setValue(int index, Object value) { + osList.setDate(index, (Date) value); } } From c871e8a515636d2739f7a46e98023393fc1f66f3 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 19 Sep 2017 12:45:44 +0900 Subject: [PATCH 70/72] use thrown.expectMessage() --- .../java/io/realm/ManagedRealmListForValueTests.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java index 9d2c12f4bc..1867051ec5 100644 --- a/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java +++ b/realm/realm-library/src/androidTest/java/io/realm/ManagedRealmListForValueTests.java @@ -955,12 +955,9 @@ public void execute(Realm realm) { @Test public void deleteAllFromRealm_outsideTransaction() { - try { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Must be in a write transaction "); list.deleteAllFromRealm(); - fail("deleteAllFromRealm should be called in a transaction."); - } catch (IllegalStateException e) { - assertThat(e.getMessage(), containsString("Must be in a write transaction ")); - } } @Test From 93a4037e2506dbc9fc4693085cd24c470814e589 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 19 Sep 2017 16:13:24 +0900 Subject: [PATCH 71/72] add Javadoc comments to ManagedListOperator and its subclasses --- .../src/main/java/io/realm/RealmList.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index 28bc18c352..d36dfbd614 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -1262,6 +1262,16 @@ private ManagedListOperator getOperator(BaseRealm realm, OsList osList, @Null } } +/** + * This class provides façade for against {@link OsList}. {@link OsList} is used for both {@link RealmModel}s + * and values, but there are some subtle differences in actual operation. + *

+ * This class provides common interface for them. + *

+ * You need to use appropriate sub-class for underlying field type. + * + * @param class of element which is returned on read operation. + */ abstract class ManagedListOperator { static final String NULL_OBJECTS_NOT_ALLOWED_MESSAGE = "RealmList does not accept null values."; static final String INVALID_OBJECT_TYPE_MESSAGE = "Unacceptable value type. Acceptable: %1$s, actual: %2$s ."; @@ -1380,6 +1390,9 @@ final void deleteAll() { } +/** + * A subclass of {@link ManagedListOperator} that deal with {@link RealmModel} list field. + */ final class RealmModelListOperator extends ManagedListOperator { @Nullable @@ -1501,6 +1514,9 @@ private E copyToRealmIfNeeded(E object) { } } +/** + * A subclass of {@link ManagedListOperator} that deal with {@link String} list field. + */ final class StringListOperator extends ManagedListOperator { StringListOperator(BaseRealm realm, OsList osList, Class clazz) { @@ -1548,6 +1564,9 @@ protected void setValue(int index, Object value) { } } +/** + * A subclass of {@link ManagedListOperator} that deal with {@code long} list field. + */ final class LongListOperator extends ManagedListOperator { LongListOperator(BaseRealm realm, OsList osList, Class clazz) { @@ -1616,6 +1635,9 @@ protected void setValue(int index, Object value) { } } +/** + * A subclass of {@link ManagedListOperator} that deal with {@code boolean} list field. + */ final class BooleanListOperator extends ManagedListOperator { BooleanListOperator(BaseRealm realm, OsList osList, Class clazz) { @@ -1663,6 +1685,9 @@ protected void setValue(int index, Object value) { } } +/** + * A subclass of {@link ManagedListOperator} that deal with {@code byte[]} list field. + */ final class BinaryListOperator extends ManagedListOperator { BinaryListOperator(BaseRealm realm, OsList osList, Class clazz) { @@ -1710,6 +1735,9 @@ protected void setValue(int index, Object value) { } } +/** + * A subclass of {@link ManagedListOperator} that deal with {@code double} list field. + */ final class DoubleListOperator extends ManagedListOperator { DoubleListOperator(BaseRealm realm, OsList osList, Class clazz) { @@ -1757,6 +1785,9 @@ protected void setValue(int index, Object value) { } } +/** + * A subclass of {@link ManagedListOperator} that deal with {@code float} list field. + */ final class FloatListOperator extends ManagedListOperator { FloatListOperator(BaseRealm realm, OsList osList, Class clazz) { @@ -1804,6 +1835,9 @@ protected void setValue(int index, Object value) { } } +/** + * A subclass of {@link ManagedListOperator} that deal with {@link Date} list field. + */ final class DateListOperator extends ManagedListOperator { DateListOperator(BaseRealm realm, OsList osList, Class clazz) { From c50e0a3121f84d34c27f925b1c89b5956031c233 Mon Sep 17 00:00:00 2001 From: Makoto Yamazaki Date: Tue, 19 Sep 2017 19:25:29 +0900 Subject: [PATCH 72/72] address review comments --- CHANGELOG.md | 1 - realm/realm-library/src/main/java/io/realm/RealmList.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 530e8eefd0..af7ba86733 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,6 @@ * `RealmResults.distinct()`/`RealmResults.distinctAsync()` have been removed. Use `RealmQuery.distinct()`/`RealmQuery.distinctAsync()` instead. * `RealmQuery.createQuery(Realm, Class)`, `RealmQuery.createDynamicQuery(DynamicRealm, String)`, `RealmQuery.createQueryFromResult(RealmResults)` and `RealmQuery.createQueryFromList(RealmList)` have been removed. Use `Realm.where(Class)`, `DynamicRealm.where(String)`, RealmResults.where()` and `RealmList.where()` instead. -* Some exception messages are revised. ### Enhancements diff --git a/realm/realm-library/src/main/java/io/realm/RealmList.java b/realm/realm-library/src/main/java/io/realm/RealmList.java index d36dfbd614..282b94f510 100644 --- a/realm/realm-library/src/main/java/io/realm/RealmList.java +++ b/realm/realm-library/src/main/java/io/realm/RealmList.java @@ -1263,7 +1263,7 @@ private ManagedListOperator getOperator(BaseRealm realm, OsList osList, @Null } /** - * This class provides façade for against {@link OsList}. {@link OsList} is used for both {@link RealmModel}s + * This class provides facade for against {@link OsList}. {@link OsList} is used for both {@link RealmModel}s * and values, but there are some subtle differences in actual operation. *

* This class provides common interface for them.