1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.room;
18 
19 import android.content.Context;
20 
21 import androidx.annotation.NonNull;
22 
23 /**
24  * Utility class for Room.
25  */
26 @SuppressWarnings("unused")
27 public class Room {
28     static final String LOG_TAG = "ROOM";
29     /**
30      * The master table where room keeps its metadata information.
31      */
32     public static final String MASTER_TABLE_NAME = RoomMasterTable.TABLE_NAME;
33     private static final String CURSOR_CONV_SUFFIX = "_CursorConverter";
34 
35     /**
36      * Creates a RoomDatabase.Builder for a persistent database. Once a database is built, you
37      * should keep a reference to it and re-use it.
38      *
39      * @param context The context for the database. This is usually the Application context.
40      * @param klass   The abstract class which is annotated with {@link Database} and extends
41      *                {@link RoomDatabase}.
42      * @param name    The name of the database file.
43      * @param <T>     The type of the database class.
44      * @return A {@code RoomDatabaseBuilder<T>} which you can use to create the database.
45      */
46     @SuppressWarnings("WeakerAccess")
47     @NonNull
databaseBuilder( @onNull Context context, @NonNull Class<T> klass, @NonNull String name)48     public static <T extends RoomDatabase> RoomDatabase.Builder<T> databaseBuilder(
49             @NonNull Context context, @NonNull Class<T> klass, @NonNull String name) {
50         //noinspection ConstantConditions
51         if (name == null || name.trim().length() == 0) {
52             throw new IllegalArgumentException("Cannot build a database with null or empty name."
53                     + " If you are trying to create an in memory database, use Room"
54                     + ".inMemoryDatabaseBuilder");
55         }
56         return new RoomDatabase.Builder<>(context, klass, name);
57     }
58 
59     /**
60      * Creates a RoomDatabase.Builder for an in memory database. Information stored in an in memory
61      * database disappears when the process is killed.
62      * Once a database is built, you should keep a reference to it and re-use it.
63      *
64      * @param context The context for the database. This is usually the Application context.
65      * @param klass   The abstract class which is annotated with {@link Database} and extends
66      *                {@link RoomDatabase}.
67      * @param <T>     The type of the database class.
68      * @return A {@code RoomDatabaseBuilder<T>} which you can use to create the database.
69      */
70     @NonNull
inMemoryDatabaseBuilder( @onNull Context context, @NonNull Class<T> klass)71     public static <T extends RoomDatabase> RoomDatabase.Builder<T> inMemoryDatabaseBuilder(
72             @NonNull Context context, @NonNull Class<T> klass) {
73         return new RoomDatabase.Builder<>(context, klass, null);
74     }
75 
76     @SuppressWarnings({"TypeParameterUnusedInFormals", "ClassNewInstance"})
77     @NonNull
getGeneratedImplementation(Class<C> klass, String suffix)78     static <T, C> T getGeneratedImplementation(Class<C> klass, String suffix) {
79         final String fullPackage = klass.getPackage().getName();
80         String name = klass.getCanonicalName();
81         final String postPackageName = fullPackage.isEmpty()
82                 ? name
83                 : (name.substring(fullPackage.length() + 1));
84         final String implName = postPackageName.replace('.', '_') + suffix;
85         //noinspection TryWithIdenticalCatches
86         try {
87 
88             @SuppressWarnings("unchecked")
89             final Class<T> aClass = (Class<T>) Class.forName(
90                     fullPackage.isEmpty() ? implName : fullPackage + "." + implName);
91             return aClass.newInstance();
92         } catch (ClassNotFoundException e) {
93             throw new RuntimeException("cannot find implementation for "
94                     + klass.getCanonicalName() + ". " + implName + " does not exist");
95         } catch (IllegalAccessException e) {
96             throw new RuntimeException("Cannot access the constructor"
97                     + klass.getCanonicalName());
98         } catch (InstantiationException e) {
99             throw new RuntimeException("Failed to create an instance of "
100                     + klass.getCanonicalName());
101         }
102     }
103 
104     /** @deprecated This type should not be instantiated as it contains only static methods. */
105     @Deprecated
106     @SuppressWarnings("PrivateConstructorForUtilityClass")
Room()107     public Room() {
108     }
109 }
110