public void generate() throws IOException { String qualifiedGeneratedClassName = String.format(Locale.US, "%s.%s", Constants.REALM_PACKAGE_NAME, Constants.DEFAULT_MODULE_CLASS_NAME); JavaFileObject sourceFile = env.getFiler().createSourceFile(qualifiedGeneratedClassName); JavaWriter writer = new JavaWriter(new BufferedWriter(sourceFile.openWriter())); writer.setIndent(" "); writer.emitPackage(Constants.REALM_PACKAGE_NAME); writer.emitEmptyLine(); Map<String, Boolean> attributes = new HashMap<String, Boolean>(); attributes.put("allClasses", Boolean.TRUE); writer.emitAnnotation(RealmModule.class, attributes); writer.beginType( qualifiedGeneratedClassName, // full qualified name of the item to generate "class", // the type of the item Collections.<Modifier>emptySet(), // modifiers to apply null); // class to extend writer.emitEmptyLine(); writer.endType(); writer.close(); }
private boolean processModules(RoundEnvironment roundEnv) { ModuleMetaData moduleMetaData = new ModuleMetaData(classesToValidate); if (!moduleMetaData.generate(roundEnv.getElementsAnnotatedWith(RealmModule.class))) { return false; } // Create default module if needed if (moduleMetaData.shouldCreateDefaultModule()) { if (!createDefaultModule()) { return false; } } // Create RealmProxyMediators for all Realm modules for (Map.Entry<String, Set<ClassMetaData>> module : moduleMetaData.getAllModules().entrySet()) { if (!createMediator(Utils.stripPackage(module.getKey()), module.getValue())) { return false; } } return true; }
/** * Returns a {@link RealmConfiguration} appropriate to open a read-only, non-synced Realm to recover any pending changes. * This is useful when trying to open a backup/recovery Realm (after a client reset). * * @param canonicalPath the absolute path to the Realm file defined by this configuration. * @param encryptionKey the key used to encrypt/decrypt the Realm file. * @param modules if specified it will restricts Realm schema to the provided module. * @return RealmConfiguration that can be used offline */ public static RealmConfiguration forRecovery(String canonicalPath, @Nullable byte[] encryptionKey, @Nullable Object... modules) { HashSet<Object> validatedModules = new HashSet<>(); if (modules != null && modules.length > 0) { for (Object module : modules) { if (!module.getClass().isAnnotationPresent(RealmModule.class)) { throw new IllegalArgumentException(module.getClass().getCanonicalName() + " is not a RealmModule. " + "Add @RealmModule to the class definition."); } validatedModules.add(module); } } else { if (Realm.getDefaultModule() != null) { validatedModules.add(Realm.getDefaultModule()); } } RealmProxyMediator schemaMediator = createSchemaMediator(validatedModules, Collections.<Class<? extends RealmModel>>emptySet()); return forRecovery(canonicalPath, encryptionKey, schemaMediator); }
private AnnotationMirror getAnnotationMirror(Element classElement) { AnnotationMirror annotationMirror = null; for (AnnotationMirror am : classElement.getAnnotationMirrors()) { if (am.getAnnotationType().toString().equals(RealmModule.class.getCanonicalName())) { annotationMirror = am; break; } } return annotationMirror; }
public void testCompositeMediatorModelClassesCount() { final CompositeMediator mediator = new CompositeMediator( new HumanModuleMediator(), new AnimalModuleMediator() ); final int modelsInHumanModule = HumanModule.class.getAnnotation(RealmModule.class).classes().length; final int modelsInAnimalModule = AnimalModule.class.getAnnotation(RealmModule.class).classes().length; assertEquals(modelsInHumanModule + modelsInAnimalModule, mediator.getModelClasses().size()); }
public void generate() throws IOException { String qualifiedGeneratedClassName = String.format(Locale.US, "%s.%sMediator", REALM_PACKAGE_NAME, className); JavaFileObject sourceFile = processingEnvironment.getFiler().createSourceFile(qualifiedGeneratedClassName); JavaWriter writer = new JavaWriter(new BufferedWriter(sourceFile.openWriter())); writer.setIndent(" "); writer.emitPackage(REALM_PACKAGE_NAME); writer.emitEmptyLine(); writer.emitImports( "android.util.JsonReader", "java.io.IOException", "java.util.Collections", "java.util.HashSet", "java.util.List", "java.util.Map", "java.util.HashMap", "java.util.Set", "java.util.Iterator", "java.util.Collection", "io.realm.internal.ColumnInfo", "io.realm.internal.RealmObjectProxy", "io.realm.internal.RealmProxyMediator", "io.realm.internal.Row", "io.realm.internal.OsSchemaInfo", "io.realm.internal.OsObjectSchemaInfo", "org.json.JSONException", "org.json.JSONObject" ); writer.emitEmptyLine(); writer.emitAnnotation(RealmModule.class); writer.beginType( qualifiedGeneratedClassName, // full qualified name of the item to generate "class", // the type of the item Collections.<Modifier>emptySet(), // modifiers to apply "RealmProxyMediator"); // class to extend writer.emitEmptyLine(); emitFields(writer); emitGetExpectedObjectSchemaInfoMap(writer); emitCreateColumnInfoMethod(writer); emitGetFieldNamesMethod(writer); emitGetSimpleClassNameMethod(writer); emitNewInstanceMethod(writer); emitGetClassModelList(writer); emitCopyToRealmMethod(writer); emitInsertObjectToRealmMethod(writer); emitInsertListToRealmMethod(writer); emitInsertOrUpdateObjectToRealmMethod(writer); emitInsertOrUpdateListToRealmMethod(writer); emitCreteOrUpdateUsingJsonObject(writer); emitCreateUsingJsonStream(writer); emitCreateDetachedCopyMethod(writer); writer.endType(); writer.close(); }
/** * Builds the meta data structures for this class. Any errors or messages will be posted on the provided Messager. * * @return True if meta data was correctly created and processing can continue, false otherwise. */ public boolean generate(Set<? extends Element> clazzes) { // Check that modules are setup correctly for (Element classElement : clazzes) { String classSimpleName = classElement.getSimpleName().toString(); // Check that the annotation is only applied to a class if (!classElement.getKind().equals(ElementKind.CLASS)) { Utils.error("The RealmModule annotation can only be applied to classes", classElement); return false; } // Check that allClasses and classes are not set at the same time RealmModule module = classElement.getAnnotation(RealmModule.class); Utils.note("Processing module " + classSimpleName); if (module.allClasses() && hasCustomClassList(classElement)) { Utils.error("Setting @RealmModule(allClasses=true) will override @RealmModule(classes={...}) in " + classSimpleName); return false; } // Check that classes added are proper Realm model classes String qualifiedName = ((TypeElement) classElement).getQualifiedName().toString(); Set<ClassMetaData> classes; if (module.allClasses()) { classes = availableClasses; } else { classes = new HashSet<ClassMetaData>(); Set<String> classNames = getClassMetaDataFromModule(classElement); for (String fullyQualifiedClassName : classNames) { ClassMetaData metadata = classMetaData.get(fullyQualifiedClassName); if (metadata == null) { Utils.error(Utils.stripPackage(fullyQualifiedClassName) + " could not be added to the module. " + "Only classes extending RealmObject, which are part of this project, can be added."); return false; } classes.add(metadata); } } // Create either a Library or App module if (module.library()) { libraryModules.put(qualifiedName, classes); } else { modules.put(qualifiedName, classes); } } // Check that app and library modules are not mixed if (modules.size() > 0 && libraryModules.size() > 0) { Utils.error("Normal modules and library modules cannot be mixed in the same project"); return false; } // Create default Realm module if needed. // Note: Kotlin will trigger the annotation processor even if no Realm annotations are used. // The DefaultRealmModule should not be created in this case either. if (libraryModules.size() == 0 && availableClasses.size() > 0) { shouldCreateDefaultModule = true; String defaultModuleName = Constants.REALM_PACKAGE_NAME + "." + Constants.DEFAULT_MODULE_CLASS_NAME; modules.put(defaultModuleName, availableClasses); } return true; }
private void checkModule(Object module) { if (!module.getClass().isAnnotationPresent(RealmModule.class)) { throw new IllegalArgumentException(module.getClass().getCanonicalName() + " is not a RealmModule. " + "Add @RealmModule to the class definition."); } }