Skip to content

Commit dda6149

Browse files
committed
add UserServiceFactoryCall
1 parent 80df7ab commit dda6149

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

src/main/java/io/getstream/chat/java/services/framework/DefaultClient.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,21 @@ public <TService> TService create(Class<TService> svcClass) {
154154
}
155155

156156
@Override
157-
public <TService> @NotNull TService create(Class<TService> svcClass, String userToken) {
157+
@NotNull
158+
public <TService> TService create(Class<TService> svcClass, String userToken) {
158159
return serviceFactory.create(svcClass, new UserToken(userToken));
159160
}
160161

161-
public <TService> @NotNull TService create2(Class<TService> svcClass, String userToken) {
162+
@NotNull
163+
public <TService> TService create2(Class<TService> svcClass, String userToken) {
162164
return new UserServiceFactoryTagging(retrofit).create(svcClass, new UserToken(userToken));
163165
}
164166

167+
@NotNull
168+
public <TService> TService create3(Class<TService> svcClass, String userToken) {
169+
return new UserServiceFactoryCall(retrofit).create(svcClass, new UserToken(userToken));
170+
}
171+
165172
@NotNull
166173
public String getApiSecret() {
167174
return apiSecret;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package io.getstream.chat.java.services.framework;
2+
3+
import retrofit2.Retrofit;
4+
5+
/**
6+
* A user service factory implementation that wraps Retrofit service calls with user token context.
7+
* <p>
8+
* This factory creates dynamic proxies around Retrofit service interfaces, intercepting method calls
9+
* to wrap any {@link retrofit2.Call} results with {@link UserCall}. This enables automatic user token
10+
* injection for client-side requests without modifying the service interface definitions.
11+
* </p>
12+
* <p>
13+
* The wrapping process is transparent to callers - they interact with the service interface normally,
14+
* but each Retrofit Call is automatically enhanced with the provided user token.
15+
* </p>
16+
*
17+
* @see UserServiceFactory
18+
* @see UserCall
19+
* @see UserToken
20+
*/
21+
final class UserServiceFactoryCall implements UserServiceFactory {
22+
23+
private final Retrofit retrofit;
24+
25+
/**
26+
* Constructs a new UserServiceFactoryCall with the specified Retrofit instance.
27+
*
28+
* @param retrofit the Retrofit instance used to create the underlying service implementations
29+
*/
30+
public UserServiceFactoryCall(Retrofit retrofit) {
31+
this.retrofit = retrofit;
32+
}
33+
34+
/**
35+
* Creates a dynamic proxy for the specified service interface that wraps Retrofit Calls with user token context.
36+
* <p>
37+
* This method generates a service implementation that intercepts all method calls. When a method returns
38+
* a {@link retrofit2.Call}, it wraps the call in a {@link UserCall} that carries the provided user token.
39+
* Non-Call return values are passed through unchanged.
40+
* </p>
41+
*
42+
* @param <TService> the service interface type
43+
* @param svcClass the service interface class to create
44+
* @param userToken the user token to inject into wrapped calls
45+
* @return a dynamic proxy implementing the service interface with automatic UserCall wrapping
46+
*/
47+
@SuppressWarnings("unchecked")
48+
public final <TService> TService create(Class<TService> svcClass, UserToken userToken) {
49+
TService delegate = retrofit.create(svcClass);
50+
51+
return (TService) java.lang.reflect.Proxy.newProxyInstance(
52+
svcClass.getClassLoader(),
53+
new Class<?>[] { svcClass },
54+
(proxy, method, args) -> {
55+
Object result = method.invoke(delegate, args);
56+
57+
// If the result is a retrofit2.Call, wrap it with UserCall
58+
if (result instanceof retrofit2.Call) {
59+
return new UserCall<>((retrofit2.Call<?>) result, userToken);
60+
}
61+
62+
return result;
63+
}
64+
);
65+
}
66+
67+
}

0 commit comments

Comments
 (0)