1 /*
2 * Copyright (C) 2022 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 com.android.libraries.pcc.chronicle.api
18
19 import com.android.libraries.pcc.chronicle.api.error.ChronicleError
20 import com.android.libraries.pcc.chronicle.api.policy.Policy
21 import kotlin.reflect.KClass
22
23 /** Chronicle is the primary entry point for features when accessing or manipulating data. */
24 interface Chronicle {
25 /**
26 * Returns the [ConnectionTypes] associated with the provided [dataTypeClass] which are available
27 * via [getConnection].
28 */
getAvailableConnectionTypesnull29 fun getAvailableConnectionTypes(dataTypeClass: KClass<*>): ConnectionTypes
30
31 /**
32 * Returns the [ConnectionTypes] associated with the provided [dataTypeClass] which are available
33 * via [getConnection].
34 */
35 fun getAvailableConnectionTypes(dataTypeClass: Class<*>): ConnectionTypes =
36 getAvailableConnectionTypes(dataTypeClass.kotlin)
37
38 /**
39 * Returns a [Connection] of type [T] after checking policy adherence of the
40 * [ConnectionRequest.requester] and the data being requested.
41 */
42 fun <T : Connection> getConnection(request: ConnectionRequest<T>): ConnectionResult<T>
43
44 /**
45 * A convenience method which calls [getConnection], returning `null` for
46 * [ConnectionResult.Failure] results. An optional [onError] parameter will be called with the
47 * failure result.
48 */
49 fun <T : Connection> getConnectionOrNull(
50 request: ConnectionRequest<T>,
51 onError: (ChronicleError) -> Unit = {}
52 ): T? {
resultnull53 return when (val result = getConnection(request)) {
54 is ConnectionResult.Success<T> -> result.connection
55 is ConnectionResult.Failure<T> -> {
56 onError(result.error)
57 null
58 }
59 }
60 }
61
62 /**
63 * A convenience method which calls [getConnection], returning `null` for
64 * [ConnectionResult.Failure] results. If a failure occurs, there will be no information provided
65 * about the failure.
66 */
getConnectionOrNullnull67 fun <T : Connection> getConnectionOrNull(
68 request: ConnectionRequest<T>,
69 ): T? = getConnectionOrNull(request) {}
70
71 /**
72 * A convenience method which calls [getConnection], and throws [ChronicleError] for
73 * [ConnectionResult.Failure] results.
74 */
getConnectionOrThrownull75 fun <T : Connection> getConnectionOrThrow(request: ConnectionRequest<T>): T {
76 return when (val result = getConnection(request)) {
77 is ConnectionResult.Success<T> -> result.connection
78 is ConnectionResult.Failure<T> -> throw (result.error)
79 }
80 }
81
82 data class ConnectionTypes(
83 val readConnections: Set<Class<out ReadConnection>>,
84 val writeConnections: Set<Class<out WriteConnection>>
85 ) {
86 companion object {
87 val EMPTY = ConnectionTypes(emptySet(), emptySet())
88 }
89 }
90 }
91
92 /** Result container for [Connection] attempts. */
93 sealed class ConnectionResult<T : Connection> {
94 class Success<T : Connection>(val connection: T) : ConnectionResult<T>()
95 class Failure<T : Connection>(val error: ChronicleError) : ConnectionResult<T>()
96 }
97
98 /**
99 * A convenience method that will create a [ConnectionRequest] using the class provided as a type
100 * parameter to the call, the provided processor, and provided policy.
101 */
getConnectionnull102 inline fun <reified T : Connection> Chronicle.getConnection(
103 requester: ProcessorNode,
104 policy: Policy? = null
105 ) = getConnection(ConnectionRequest(T::class.java, requester, policy))
106
107 /**
108 * A convenience method that will create a [ConnectionRequest] using the class provided as a type
109 * parameter to the call, the provided processor, and provided policy.
110 *
111 * An optional [onError] callback will be called with the [ChronicleError] containing the failure
112 * reason if the connection fails.
113 */
114 inline fun <reified T : Connection> Chronicle.getConnectionOrNull(
115 requester: ProcessorNode,
116 policy: Policy? = null,
117 noinline onError: (ChronicleError) -> Unit = {}
118 ) = getConnectionOrNull(ConnectionRequest(T::class.java, requester, policy), onError)
119
120 /**
121 * A convenience method that will create a [ConnectionRequest] using the class provided as a type
122 * parameter to the call, the provided processor, and provided policy.
123 */
getConnectionOrThrownull124 inline fun <reified T : Connection> Chronicle.getConnectionOrThrow(
125 requester: ProcessorNode,
126 policy: Policy? = null
127 ) = getConnectionOrThrow(ConnectionRequest(T::class.java, requester, policy))
128