private void addRealmAnnotations(Field f, SpannableStringBuilder builder) { List<Class<? extends Annotation>> classes = new ArrayList<>(3); classes.add(PrimaryKey.class); classes.add(Ignore.class); classes.add(Index.class); for (Class<? extends Annotation> c : classes) { if (f.isAnnotationPresent(c)) { addAnnotationName(builder, f.getAnnotation(c)); } } }
private boolean categorizeField(Element element) { VariableElement field = (VariableElement) element; // completely ignore any static fields if (field.getModifiers().contains(Modifier.STATIC)) { return true; } // Ignore fields marked with @Ignore or if they are transient if (field.getAnnotation(Ignore.class) != null || field.getModifiers().contains(Modifier.TRANSIENT)) { return true; } if (field.getAnnotation(Index.class) != null) { if (!categorizeIndexField(element, field)) { return false; } } // @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 List<? extends TypeMirror> fieldTypeArguments = ((DeclaredType) field.asType()).getTypeArguments(); if (fieldTypeArguments.isEmpty() || !Utils.isRealmModel(fieldTypeArguments.get(0))) { nullableValueListFields.add(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 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); } } if (field.getAnnotation(PrimaryKey.class) != null) { if (!categorizePrimaryKeyField(field)) { return false; } } // @LinkingObjects cannot be @PrimaryKey or @Index. if (field.getAnnotation(LinkingObjects.class) != null) { // Do not add backlinks to fields list. return categorizeBacklinkField(field); } // Similarly, a MutableRealmInteger cannot be a @PrimaryKey or @LinkingObject. if (Utils.isMutableRealmInteger(field)) { if (!categorizeMutableRealmIntegerField(field)) { return false; } } // Standard field that appears to be valid (more fine grained checks might fail later). fields.add(field); return true; }
private static void matchMigratedField(RealmObjectSchema objectSchema, String modelFieldName, Field field) { boolean isIndexed = false; boolean isRequired = false; boolean isPrimaryKey = false; if(field.isAnnotationPresent(Index.class)) { isIndexed = true; } if(field.isAnnotationPresent(Required.class)) { isRequired = true; } if(field.isAnnotationPresent(PrimaryKey.class)) { isPrimaryKey = true; } if(isPrimaryKey && !objectSchema.isPrimaryKey(modelFieldName)) { if(objectSchema.hasPrimaryKey()) { objectSchema.removePrimaryKey(); } objectSchema.addPrimaryKey(modelFieldName); } if(!isPrimaryKey && objectSchema.isPrimaryKey(modelFieldName)) { objectSchema.removePrimaryKey(); } // index management must be after primary key because removePrimaryKey() removes index as well. if((isIndexed || isPrimaryKey) && !objectSchema.hasIndex(modelFieldName)) { objectSchema.addIndex(modelFieldName); } if(!isIndexed && !isPrimaryKey /* primary key is indexed by default! */ && objectSchema.hasIndex(modelFieldName)) { objectSchema.removeIndex(modelFieldName); } if(isNonNullPrimitive(field.getType())) { if(!objectSchema.isRequired(modelFieldName)) { objectSchema.setNullable(modelFieldName, false); } } else { if(isRequired && objectSchema.isNullable(modelFieldName)) { objectSchema.setNullable(modelFieldName, false); } if(!isRequired && !objectSchema.isNullable(modelFieldName)) { objectSchema.setNullable(modelFieldName, true); } } }