/** * Validate the source side of the backlink. * * @return true if the backlink source looks good. */ public boolean validateSource() { // A @LinkingObjects cannot be @Required if (backlink.getAnnotation(Required.class) != null) { Utils.error(String.format( Locale.US, "The @LinkingObjects field \"%s.%s\" cannot be @Required.", targetClass, targetField)); return false; } // The annotation must have an argument, identifying the linked field if ((sourceField == null) || sourceField.equals("")) { Utils.error(String.format( Locale.US, "The @LinkingObjects annotation for the field \"%s.%s\" must have a parameter identifying the link target.", targetClass, targetField)); return false; } // Using link syntax to try to reference a linked field is not possible. if (sourceField.contains(".")) { Utils.error(String.format( Locale.US, "The parameter to the @LinkingObjects annotation for the field \"%s.%s\" contains a '.'. The use of '.' to specify fields in referenced classes is not supported.", targetClass, targetField)); return false; } // The annotated element must be a RealmResult if (!Utils.isRealmResults(backlink)) { Utils.error(String.format( Locale.US, "The field \"%s.%s\" is a \"%s\". Fields annotated with @LinkingObjects must be RealmResults.", targetClass, targetField, backlink.asType())); return false; } if (sourceClass == null) { Utils.error(String.format( Locale.US, "\"The field \"%s.%s\", annotated with @LinkingObjects, must specify a generic type.", targetClass, targetField)); return false; } // A @LinkingObjects field must be final if (!backlink.getModifiers().contains(Modifier.FINAL)) { Utils.error(String.format( Locale.US, "A @LinkingObjects field \"%s.%s\" must be final.", targetClass, targetField)); return false; } 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); } } }
/** * 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; }