36
36
@ KeepForSdk
37
37
public final class Component <T > {
38
38
39
+ /** Specifies instantiation behavior of a {@link Component}. */
39
40
@ IntDef ({Instantiation .LAZY , Instantiation .ALWAYS_EAGER , Instantiation .EAGER_IN_DEFAULT_APP })
40
41
@ Retention (RetentionPolicy .SOURCE )
41
42
private @interface Instantiation {
43
+ /** Component is not instantiated until requested by developer or a dependent component. */
42
44
int LAZY = 0 ;
45
+
46
+ /**
47
+ * Component is unconditionally instantiated upon startup of the {@link ComponentRuntime}.
48
+ *
49
+ * <p>Namely when {@link ComponentRuntime#initializeEagerComponents(boolean)} is called.
50
+ */
43
51
int ALWAYS_EAGER = 1 ;
52
+
53
+ /**
54
+ * Component is instantiated upon startup of the {@link ComponentRuntime} if the runtime is
55
+ * initialized for the default app.
56
+ */
44
57
int EAGER_IN_DEFAULT_APP = 2 ;
45
58
}
46
59
60
+ /** Specifies the type of a {@link Component}. */
61
+ @ IntDef ({ComponentType .VALUE , ComponentType .SET })
62
+ @ Retention (RetentionPolicy .SOURCE )
63
+ private @interface ComponentType {
64
+ /**
65
+ * Value components provide scalar values to the {@link ComponentRuntime}.
66
+ *
67
+ * <p>Such components can be requested by dependents via {@link ComponentContainer#get(Class)}
68
+ * or {@link ComponentContainer#getProvider(Class)}. e.g. {@code FirebaseInstanceId}.
69
+ */
70
+ int VALUE = 0 ;
71
+
72
+ /**
73
+ * Set components collectively contribute values of type {@code T} to a {@link Set
74
+ * Set<T>}.
75
+ *
76
+ * <p>Such components can be requested by dependents via {@link ComponentContainer#setOf(Class)}
77
+ * or {@link ComponentContainer#setOfProvider(Class)}.
78
+ */
79
+ int SET = 1 ;
80
+ }
81
+
47
82
private final Set <Class <? super T >> providedInterfaces ;
48
83
private final Set <Dependency > dependencies ;
49
84
private final @ Instantiation int instantiation ;
85
+ private final @ ComponentType int type ;
50
86
private final ComponentFactory <T > factory ;
51
87
private final Set <Class <?>> publishedEvents ;
52
88
53
89
private Component (
54
90
Set <Class <? super T >> providedInterfaces ,
55
91
Set <Dependency > dependencies ,
56
92
@ Instantiation int instantiation ,
93
+ @ ComponentType int type ,
57
94
ComponentFactory <T > factory ,
58
95
Set <Class <?>> publishedEvents ) {
59
96
this .providedInterfaces = Collections .unmodifiableSet (providedInterfaces );
60
97
this .dependencies = Collections .unmodifiableSet (dependencies );
61
98
this .instantiation = instantiation ;
99
+ this .type = type ;
62
100
this .factory = factory ;
63
101
this .publishedEvents = Collections .unmodifiableSet (publishedEvents );
64
102
}
@@ -113,30 +151,38 @@ public boolean isEagerInDefaultApp() {
113
151
return instantiation == Instantiation .EAGER_IN_DEFAULT_APP ;
114
152
}
115
153
154
+ /** Returns whether a component is a Value Component or a Set Component. */
155
+ public boolean isValue () {
156
+ return type == ComponentType .VALUE ;
157
+ }
158
+
116
159
@ Override
117
160
public String toString () {
118
161
StringBuilder sb =
119
162
new StringBuilder ("Component<" )
120
163
.append (Arrays .toString (providedInterfaces .toArray ()))
121
164
.append (">{" )
122
165
.append (instantiation )
166
+ .append (", type=" )
167
+ .append (type )
123
168
.append (", deps=" )
124
169
.append (Arrays .toString (dependencies .toArray ()))
125
170
.append ("}" );
126
171
return sb .toString ();
127
172
}
128
173
129
- @ KeepForSdk
130
174
/** Returns a Component<T> builder. */
175
+ @ KeepForSdk
131
176
public static <T > Component .Builder <T > builder (Class <T > anInterface ) {
132
- return new Builder <T >(anInterface );
177
+ return new Builder <>(anInterface );
133
178
}
134
179
135
- @ KeepForSdk
136
180
/** Returns a Component<T> builder. */
181
+ @ KeepForSdk
182
+ @ SafeVarargs
137
183
public static <T > Component .Builder <T > builder (
138
184
Class <T > anInterface , Class <? super T >... additionalInterfaces ) {
139
- return new Builder <T >(anInterface , additionalInterfaces );
185
+ return new Builder <>(anInterface , additionalInterfaces );
140
186
}
141
187
142
188
/**
@@ -151,22 +197,46 @@ public static <T> Component<T> of(Class<T> anInterface, T value) {
151
197
}
152
198
153
199
/** Wraps a value in a {@link Component} with no dependencies. */
154
- @ SafeVarargs
155
200
@ KeepForSdk
201
+ @ SafeVarargs
156
202
public static <T > Component <T > of (
157
203
T value , Class <T > anInterface , Class <? super T >... additionalInterfaces ) {
158
204
return builder (anInterface , additionalInterfaces ).factory ((args ) -> value ).build ();
159
205
}
160
206
207
+ /**
208
+ * Provides a builder for a {@link Set}-multibinding {@link Component}.
209
+ *
210
+ * <p>Such components can be requested by dependents via {@link ComponentContainer#setOf(Class)} *
211
+ * or {@link ComponentContainer#setOfProvider(Class)}.
212
+ */
213
+ @ KeepForSdk
214
+ public static <T > Component .Builder <T > intoSetBuilder (Class <T > anInterface ) {
215
+ return builder (anInterface ).intoSet ();
216
+ }
217
+
218
+ /**
219
+ * Wraps a value in a {@link Set}-multibinding {@link Component} with no dependencies. *
220
+ *
221
+ * <p>Such components can be requested by dependents via {@link ComponentContainer#setOf(Class)} *
222
+ * or {@link ComponentContainer#setOfProvider(Class)}.
223
+ */
224
+ @ KeepForSdk
225
+ public static <T > Component <T > intoSet (T value , Class <T > anInterface ) {
226
+ return intoSetBuilder (anInterface ).factory (c -> value ).build ();
227
+ }
228
+
161
229
/** FirebaseComponent builder. */
162
230
@ KeepForSdk
163
231
public static class Builder <T > {
164
232
private final Set <Class <? super T >> providedInterfaces = new HashSet <>();
165
233
private final Set <Dependency > dependencies = new HashSet <>();
166
234
private @ Instantiation int instantiation = Instantiation .LAZY ;
235
+ private @ ComponentType int type = ComponentType .VALUE ;
167
236
private ComponentFactory <T > factory ;
168
237
private Set <Class <?>> publishedEvents = new HashSet <>();
169
238
239
+ @ SafeVarargs
170
240
private Builder (Class <T > anInterface , Class <? super T >... additionalInterfaces ) {
171
241
Preconditions .checkNotNull (anInterface , "Null interface" );
172
242
providedInterfaces .add (anInterface );
@@ -176,6 +246,7 @@ private Builder(Class<T> anInterface, Class<? super T>... additionalInterfaces)
176
246
Collections .addAll (providedInterfaces , additionalInterfaces );
177
247
}
178
248
249
+ /** Add a {@link Dependency} to the {@link Component} being built. */
179
250
@ KeepForSdk
180
251
public Builder <T > add (Dependency dependency ) {
181
252
Preconditions .checkNotNull (dependency , "Null dependency" );
@@ -184,16 +255,19 @@ public Builder<T> add(Dependency dependency) {
184
255
return this ;
185
256
}
186
257
258
+ /** Make the {@link Component} initialize upon startup. */
187
259
@ KeepForSdk
188
260
public Builder <T > alwaysEager () {
189
261
return setInstantiation (Instantiation .ALWAYS_EAGER );
190
262
}
191
263
264
+ /** Make the component initialize upon startup in default app. */
192
265
@ KeepForSdk
193
266
public Builder <T > eagerInDefaultApp () {
194
267
return setInstantiation (Instantiation .EAGER_IN_DEFAULT_APP );
195
268
}
196
269
270
+ /** Make the {@link Component} eligible to publish events of provided eventType. */
197
271
@ KeepForSdk
198
272
public Builder <T > publishes (Class <?> eventType ) {
199
273
publishedEvents .add (eventType );
@@ -213,19 +287,27 @@ private void validateInterface(Class<?> anInterface) {
213
287
"Components are not allowed to depend on interfaces they themselves provide." );
214
288
}
215
289
290
+ /** Set the factory that will be used to initialize the {@link Component}. */
216
291
@ KeepForSdk
217
292
public Builder <T > factory (ComponentFactory <T > value ) {
218
293
factory = Preconditions .checkNotNull (value , "Null factory" );
219
294
return this ;
220
295
}
221
296
297
+ private Builder <T > intoSet () {
298
+ type = ComponentType .SET ;
299
+ return this ;
300
+ }
301
+
302
+ /** Return the built {@link Component} definition. */
222
303
@ KeepForSdk
223
304
public Component <T > build () {
224
305
Preconditions .checkState (factory != null , "Missing required property: factory." );
225
306
return new Component <>(
226
307
new HashSet <>(providedInterfaces ),
227
308
new HashSet <>(dependencies ),
228
309
instantiation ,
310
+ type ,
229
311
factory ,
230
312
publishedEvents );
231
313
}
0 commit comments