1 /*
2 * Copyright 2024 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 @file:JvmName("KClassUtil")
18 @file:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) // used in generated code
19
20 package androidx.room.util
21
22 import androidx.annotation.RestrictTo
23
24 /**
25 * Finds and instantiates via reflection the implementation class generated by Room of an
26 * `@Database` annotated type.
27 */
28 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) // used in generated code
findAndInstantiateDatabaseImplnull29 fun <T, C> findAndInstantiateDatabaseImpl(klass: Class<C>, suffix: String = "_Impl"): T {
30 val fullPackage: String = klass.getPackage()?.name ?: ""
31 val name: String = klass.canonicalName!!
32 val postPackageName =
33 if (fullPackage.isEmpty()) name else name.substring(fullPackage.length + 1)
34 val implName = postPackageName.replace('.', '_') + suffix
35 return try {
36 val fullClassName =
37 if (fullPackage.isEmpty()) {
38 implName
39 } else {
40 "$fullPackage.$implName"
41 }
42 @Suppress("UNCHECKED_CAST")
43 val aClass = Class.forName(fullClassName, true, klass.classLoader) as Class<T>
44 aClass.getDeclaredConstructor().newInstance()
45 } catch (e: ClassNotFoundException) {
46 throw RuntimeException(
47 "Cannot find implementation for ${klass.canonicalName}. $implName does not " +
48 "exist. Is Room annotation processor correctly configured?",
49 e
50 )
51 } catch (e: IllegalAccessException) {
52 throw RuntimeException("Cannot access the constructor ${klass.canonicalName}", e)
53 } catch (e: InstantiationException) {
54 throw RuntimeException("Failed to create an instance of ${klass.canonicalName}", e)
55 }
56 }
57