use of javax.lang.model.element.VariableElement in project realm-java by realm.
the class RealmProxyClassGenerator method emitValidateTableMethod.
private void emitValidateTableMethod(JavaWriter writer) throws IOException {
writer.beginMethod(// Return type
columnInfoClassName(), // Method name
"validateTable", // Modifiers
EnumSet.of(Modifier.PUBLIC, Modifier.STATIC), // Argument type & argument name
"SharedRealm", // Argument type & argument name
"sharedRealm", "boolean", "allowExtraColumns");
writer.beginControlFlow("if (!sharedRealm.hasTable(\"" + Constants.TABLE_PREFIX + this.simpleClassName + "\"))");
emitMigrationNeededException(writer, "\"The '%s' class is missing from the schema for this Realm.\")", metadata.getSimpleClassName());
writer.endControlFlow();
writer.emitStatement("Table table = sharedRealm.getTable(\"%s%s\")", Constants.TABLE_PREFIX, this.simpleClassName);
// verify number of columns
writer.emitStatement("final long columnCount = table.getColumnCount()");
writer.beginControlFlow("if (columnCount != %d)", metadata.getFields().size());
writer.beginControlFlow("if (columnCount < %d)", metadata.getFields().size());
emitMigrationNeededException(writer, "\"Field count is less than expected - expected %d but was \" + columnCount)", metadata.getFields().size());
writer.endControlFlow();
writer.beginControlFlow("if (allowExtraColumns)");
writer.emitStatement("RealmLog.debug(\"Field count is more than expected - expected %d but was %%1$d\", columnCount)", metadata.getFields().size());
writer.nextControlFlow("else");
emitMigrationNeededException(writer, "\"Field count is more than expected - expected %d but was \" + columnCount)", metadata.getFields().size());
writer.endControlFlow();
writer.endControlFlow();
// create type dictionary for lookup
writer.emitStatement("Map<String, RealmFieldType> columnTypes = new HashMap<String, RealmFieldType>()");
writer.beginControlFlow("for (long i = 0; i < columnCount; i++)").emitStatement("columnTypes.put(table.getColumnName(i), table.getColumnType(i))").endControlFlow().emitEmptyLine();
// create an instance of ColumnInfo
writer.emitStatement("final %1$s columnInfo = new %1$s(sharedRealm.getPath(), table)", columnInfoClassName()).emitEmptyLine();
// verify primary key definition was not altered
if (metadata.hasPrimaryKey()) {
// the current model defines a PK, make sure it's defined in the Realm schema
String fieldName = metadata.getPrimaryKey().getSimpleName().toString();
writer.beginControlFlow("if (!table.hasPrimaryKey())");
emitMigrationNeededException(writer, "\"Primary key not defined for field '%s' in existing Realm file. @PrimaryKey was added.\")", metadata.getPrimaryKey().getSimpleName().toString());
writer.nextControlFlow("else").beginControlFlow("if (table.getPrimaryKey() != columnInfo.%sIndex)", fieldName);
emitMigrationNeededException(writer, "\"Primary Key annotation definition was changed, from field \" + table.getColumnName(table.getPrimaryKey()) + \" to field %s\")", metadata.getPrimaryKey().getSimpleName().toString());
writer.endControlFlow().endControlFlow();
} else {
// the current model doesn't define a PK, make sure it's not defined in the Realm schema
writer.beginControlFlow("if (table.hasPrimaryKey())");
emitMigrationNeededException(writer, "\"Primary Key defined for field \" + table.getColumnName(table.getPrimaryKey()) + \" was removed.\")");
writer.endControlFlow();
}
writer.emitEmptyLine();
// For each field verify there is a corresponding
long fieldIndex = -1;
for (VariableElement field : metadata.getFields()) {
fieldIndex++;
String fieldName = field.getSimpleName().toString();
String fieldTypeQualifiedName = Utils.getFieldTypeQualifiedName(field);
if (Constants.JAVA_TO_REALM_TYPES.containsKey(fieldTypeQualifiedName)) {
emitValidateRealmType(writer, field, fieldName, fieldTypeQualifiedName);
} else if (Utils.isRealmModel(field)) {
// Links
emitValidateRealmModelType(writer, field, fieldIndex, fieldName);
} else if (Utils.isRealmList(field)) {
// Link Lists
emitValidateRealmListType(writer, field, fieldIndex, fieldName);
}
}
// verify the backlinks
Set<Backlink> backlinks = metadata.getBacklinkFields();
if (backlinks.size() > 0) {
writer.emitEmptyLine().emitStatement("long backlinkFieldIndex").emitStatement("Table backlinkSourceTable").emitStatement("Table backlinkTargetTable").emitStatement("RealmFieldType backlinkFieldType");
for (Backlink backlink : metadata.getBacklinkFields()) {
emitValidateBacklink(writer, backlink);
}
}
writer.emitEmptyLine();
writer.emitStatement("return %s", "columnInfo");
writer.endMethod();
writer.emitEmptyLine();
}
use of javax.lang.model.element.VariableElement in project realm-java by realm.
the class RealmProxyClassGenerator method emitColumnIndicesClass.
private void emitColumnIndicesClass(JavaWriter writer) throws IOException {
writer.beginType(// full qualified name of the item to generate
columnInfoClassName(), // the type of the item
"class", // modifiers to apply
EnumSet.of(Modifier.STATIC, Modifier.FINAL), // base class
"ColumnInfo", // interfaces
"Cloneable").emitEmptyLine();
// fields
for (VariableElement variableElement : metadata.getFields()) {
writer.emitField("long", columnIndexVarName(variableElement), EnumSet.of(Modifier.PUBLIC));
}
writer.emitEmptyLine();
// constructor
writer.beginConstructor(EnumSet.noneOf(Modifier.class), "String", "path", "Table", "table");
writer.emitStatement("final Map<String, Long> indicesMap = new HashMap<String, Long>(%s)", metadata.getFields().size());
for (VariableElement variableElement : metadata.getFields()) {
final String columnName = variableElement.getSimpleName().toString();
final String columnIndexVarName = columnIndexVarName(variableElement);
writer.emitStatement("this.%s = getValidColumnIndex(path, table, \"%s\", \"%s\")", columnIndexVarName, simpleClassName, columnName).emitStatement("indicesMap.put(\"%s\", this.%s)", columnName, columnIndexVarName);
}
writer.emitEmptyLine().emitStatement("setIndicesMap(indicesMap)");
writer.endConstructor().emitEmptyLine();
// copyColumnInfoFrom method
writer.emitAnnotation("Override").beginMethod(// return type
"void", // method name
"copyColumnInfoFrom", // modifiers
EnumSet.of(Modifier.PUBLIC, Modifier.FINAL), "ColumnInfo", // parameters
"other");
{
writer.emitStatement("final %1$s otherInfo = (%1$s) other", columnInfoClassName());
// copy field values
for (VariableElement variableElement : metadata.getFields()) {
writer.emitStatement("this.%1$s = otherInfo.%1$s", columnIndexVarName(variableElement));
}
writer.emitEmptyLine().emitStatement("setIndicesMap(otherInfo.getIndicesMap())");
}
writer.endMethod().emitEmptyLine();
// clone method
writer.emitAnnotation("Override").beginMethod(// return type
columnInfoClassName(), // method name
"clone", // modifiers
EnumSet.of(Modifier.PUBLIC, Modifier.FINAL)).emitStatement("return (%1$s) super.clone()", columnInfoClassName()).endMethod().emitEmptyLine();
writer.endType();
}
use of javax.lang.model.element.VariableElement in project realm-java by realm.
the class RealmProxyClassGenerator method emitInsertListMethod.
private void emitInsertListMethod(JavaWriter writer) throws IOException {
writer.beginMethod(// Return type
"void", // Method name
"insert", // Modifiers
EnumSet.of(Modifier.PUBLIC, Modifier.STATIC), // Argument type & argument name
"Realm", // Argument type & argument name
"realm", // Argument type & argument name
"Iterator<? extends RealmModel>", // Argument type & argument name
"objects", // Argument type & argument name
"Map<RealmModel,Long>", // Argument type & argument name
"cache");
writer.emitStatement("Table table = realm.getTable(%s.class)", qualifiedClassName);
writer.emitStatement("long tableNativePtr = table.getNativeTablePointer()");
writer.emitStatement("%s columnInfo = (%s) realm.schema.getColumnInfo(%s.class)", columnInfoClassName(), columnInfoClassName(), qualifiedClassName);
if (metadata.hasPrimaryKey()) {
writer.emitStatement("long pkColumnIndex = table.getPrimaryKey()");
}
writer.emitStatement("%s object = null", qualifiedClassName);
writer.beginControlFlow("while (objects.hasNext())").emitStatement("object = (%s) objects.next()", qualifiedClassName);
writer.beginControlFlow("if(!cache.containsKey(object))");
writer.beginControlFlow("if (object instanceof RealmObjectProxy && ((RealmObjectProxy)object).realmGet$proxyState().getRealm$realm() != null && ((RealmObjectProxy)object).realmGet$proxyState().getRealm$realm().getPath().equals(realm.getPath()))");
writer.emitStatement("cache.put(object, ((RealmObjectProxy)object).realmGet$proxyState().getRow$realm().getIndex())").emitStatement("continue");
writer.endControlFlow();
addPrimaryKeyCheckIfNeeded(metadata, true, writer);
for (VariableElement field : metadata.getFields()) {
String fieldName = field.getSimpleName().toString();
String fieldType = field.asType().toString();
String getter = metadata.getInternalGetter(fieldName);
if (Utils.isRealmModel(field)) {
writer.emitEmptyLine().emitStatement("%s %sObj = ((%s) object).%s()", fieldType, fieldName, interfaceName, getter).beginControlFlow("if (%sObj != null)", fieldName).emitStatement("Long cache%1$s = cache.get(%1$sObj)", fieldName).beginControlFlow("if (cache%s == null)", fieldName).emitStatement("cache%s = %s.insert(realm, %sObj, cache)", fieldName, Utils.getProxyClassSimpleName(field), fieldName).endControlFlow().emitStatement("table.setLink(columnInfo.%1$sIndex, rowIndex, cache%1$s, false)", fieldName).endControlFlow();
} else if (Utils.isRealmList(field)) {
final String genericType = Utils.getGenericTypeQualifiedName(field);
writer.emitEmptyLine().emitStatement("RealmList<%s> %sList = ((%s) object).%s()", genericType, fieldName, interfaceName, getter).beginControlFlow("if (%sList != null)", fieldName).emitStatement("long %1$sNativeLinkViewPtr = Table.nativeGetLinkView(tableNativePtr, columnInfo.%1$sIndex, rowIndex)", fieldName).beginControlFlow("for (%1$s %2$sItem : %2$sList)", genericType, fieldName).emitStatement("Long cacheItemIndex%1$s = cache.get(%1$sItem)", fieldName).beginControlFlow("if (cacheItemIndex%s == null)", fieldName).emitStatement("cacheItemIndex%1$s = %2$s.insert(realm, %1$sItem, cache)", fieldName, Utils.getProxyClassSimpleName(field)).endControlFlow().emitStatement("LinkView.nativeAdd(%1$sNativeLinkViewPtr, cacheItemIndex%1$s)", fieldName).endControlFlow().endControlFlow().emitEmptyLine();
} else {
if (metadata.getPrimaryKey() != field) {
setTableValues(writer, fieldType, fieldName, interfaceName, getter, false);
}
}
}
writer.endControlFlow();
writer.endControlFlow();
writer.endMethod();
writer.emitEmptyLine();
}
use of javax.lang.model.element.VariableElement in project realm-java by realm.
the class RealmProxyInterfaceGenerator method generate.
public void generate() throws IOException {
String qualifiedGeneratedInterfaceName = String.format("%s.%s", Constants.REALM_PACKAGE_NAME, Utils.getProxyInterfaceName(className));
JavaFileObject sourceFile = processingEnvironment.getFiler().createSourceFile(qualifiedGeneratedInterfaceName);
JavaWriter writer = new JavaWriter(new BufferedWriter(sourceFile.openWriter()));
writer.setIndent(Constants.INDENT);
writer.emitPackage(Constants.REALM_PACKAGE_NAME).emitEmptyLine().beginType(qualifiedGeneratedInterfaceName, "interface", EnumSet.of(Modifier.PUBLIC));
for (VariableElement field : metaData.getFields()) {
// The field is neither static nor ignored
if (!field.getModifiers().contains(Modifier.STATIC) && field.getAnnotation(Ignore.class) == null) {
String fieldName = field.getSimpleName().toString();
String fieldTypeCanonicalName = field.asType().toString();
writer.beginMethod(fieldTypeCanonicalName, metaData.getInternalGetter(fieldName), EnumSet.of(Modifier.PUBLIC)).endMethod().beginMethod("void", metaData.getInternalSetter(fieldName), EnumSet.of(Modifier.PUBLIC), fieldTypeCanonicalName, "value").endMethod();
}
}
// backlinks are final and have only a getter.
for (Backlink backlink : metaData.getBacklinkFields()) {
writer.beginMethod(backlink.getTargetFieldType(), metaData.getInternalGetter(backlink.getTargetField()), EnumSet.of(Modifier.PUBLIC)).endMethod();
}
writer.endType();
writer.close();
}
use of javax.lang.model.element.VariableElement in project realm-java by realm.
the class Backlink method validateTarget.
public boolean validateTarget(ClassMetaData clazz) {
VariableElement field = clazz.getDeclaredField(sourceField);
if (field == null) {
Utils.error(String.format("Field \"%s\", the target of the @LinkedObjects annotation on field \"%s.%s\", does not exist in class \"%s\".", sourceField, targetClass, targetField, sourceClass));
return false;
}
String fieldType = field.asType().toString();
if (!(targetClass.equals(fieldType) || targetClass.equals(Utils.getRealmListType(field)))) {
Utils.error(String.format("Field \"%s.%s\", the target of the @LinkedObjects annotation on field \"%s.%s\", has type \"%s\" instead of \"%3$s\".", sourceClass, sourceField, targetClass, targetField, fieldType));
return false;
}
return true;
}
Aggregations