0
# Runtime Marshaling Framework
1
2
Runtime utilities for JSON marshaling, async operations, and framework integrations. These components provide the foundation for serialization, database operations, and integration with popular Java frameworks.
3
4
## Capabilities
5
6
### Core Marshaling
7
8
Abstract base class for JSON marshaling of immutable objects.
9
10
```java { .api }
11
/**
12
* Abstract marshaler for type T, providing JSON serialization and deserialization
13
* capabilities. Generated marshalers extend this class to handle specific types.
14
*/
15
public abstract class Marshaler<T> {
16
17
/** Unmarshal single instance from JSON parser */
18
public abstract T unmarshalInstance(@WillNotClose JsonParser parser) throws IOException;
19
20
/** Unmarshal collection of instances from JSON parser */
21
public abstract Iterable<T> unmarshalIterable(@WillNotClose JsonParser parser) throws IOException;
22
23
/** Marshal single instance to JSON generator */
24
public abstract void marshalInstance(@WillNotClose JsonGenerator generator, T instance) throws IOException;
25
26
/** Marshal collection of instances to JSON generator */
27
public abstract void marshalIterable(@WillNotClose JsonGenerator generator, Iterable<T> iterable) throws IOException;
28
29
/** Get the expected type this marshaler handles */
30
public abstract Class<T> getExpectedType();
31
}
32
```
33
34
### Marshaling Utilities
35
36
Convenient static methods for JSON marshaling operations.
37
38
```java { .api }
39
/**
40
* Utility class providing convenient methods for JSON marshaling and unmarshaling
41
* of objects using generated marshalers.
42
*/
43
public final class Marshaling {
44
45
/** Convert object to pretty-printed JSON string */
46
public static String toJson(Object object);
47
48
/** Parse JSON string to object of expected type */
49
public static <T> T fromJson(String json, Class<? extends T> expectedType);
50
51
/** Get marshaler instance for specified type */
52
public static <T> Marshaler<T> marshalerFor(Class<? extends T> expectedType);
53
54
/** Set fallback Jackson ObjectCodec for unknown types */
55
public static void setFallbackCodec(@Nullable ObjectCodec fallbackCodec);
56
57
/** Get currently configured fallback ObjectCodec */
58
public static ObjectCodec getFallbackCodec();
59
}
60
```
61
62
**Usage Examples:**
63
64
```java
65
import org.immutables.common.marshal.Marshaling;
66
67
// Convert immutable object to JSON
68
Person person = ImmutablePerson.builder()
69
.name("Alice")
70
.age(30)
71
.build();
72
String json = Marshaling.toJson(person);
73
System.out.println(json); // {"name":"Alice","age":30}
74
75
// Parse JSON back to object
76
Person parsed = Marshaling.fromJson(json, Person.class);
77
assert person.equals(parsed);
78
79
// Get marshaler for advanced usage
80
Marshaler<Person> marshaler = Marshaling.marshalerFor(Person.class);
81
```
82
83
## Repository Framework
84
85
### Repository Base Class
86
87
Abstract base class for MongoDB repository operations with async futures.
88
89
```java { .api }
90
/**
91
* Abstract base class for repository implementations providing
92
* MongoDB operations with FluentFuture return types.
93
*/
94
public static abstract class Repositories.Repository<T> {
95
96
/**
97
* Create repository with configuration, collection name, and marshaler
98
* @param configuration Database setup and executor configuration
99
* @param collectionName MongoDB collection name
100
* @param marshaler Marshaler for type T
101
*/
102
protected Repository(RepositorySetup configuration, String collectionName, Marshaler<T> marshaler);
103
}
104
```
105
106
### Repository Setup
107
108
Configuration class for repository database connections and executors.
109
110
```java { .api }
111
/**
112
* Configuration setup for repository connections, providing database
113
* connection and executor configuration for async operations.
114
*/
115
public final class RepositorySetup {
116
117
/** Create setup builder */
118
public static Builder builder();
119
120
/** Create setup from MongoDB URI string */
121
public static RepositorySetup forUri(String uri);
122
123
/**
124
* Builder for repository setup configuration
125
*/
126
public static class Builder {
127
/** Set executor service for async operations */
128
public Builder executor(ListeningExecutorService executor);
129
130
/** Set MongoDB database instance */
131
public Builder database(DB database);
132
133
/** Build final repository setup */
134
public RepositorySetup build();
135
}
136
}
137
```
138
139
**Usage Example:**
140
141
```java
142
import org.immutables.common.repository.RepositorySetup;
143
import org.immutables.common.repository.Repositories;
144
145
// Setup repository configuration
146
RepositorySetup setup = RepositorySetup.builder()
147
.database(mongoClient.getDB("myapp"))
148
.executor(MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()))
149
.build();
150
151
// Create repository (typically auto-generated)
152
@Mongo.Repository("users")
153
public abstract class UserRepository extends Repositories.Repository<User> {
154
public UserRepository(RepositorySetup setup) {
155
super(setup, "users", UserMarshaler.instance());
156
}
157
}
158
```
159
160
## Async Utilities
161
162
### FluentFuture Interface
163
164
Enhanced ListenableFuture with fluent method chaining for async operations.
165
166
```java { .api }
167
/**
168
* Enhanced ListenableFuture interface providing fluent method chaining,
169
* transformation capabilities, and improved error handling for async operations.
170
*/
171
public interface FluentFuture<V> extends ListenableFuture<V> {
172
173
/** Get result with unchecked exception handling */
174
V getUnchecked();
175
176
/** Add completion callback, returning this future for chaining */
177
FluentFuture<V> addCallback(FutureCallback<V> callback);
178
179
/** Add fallback handling for failures */
180
FluentFuture<V> withFallback(FutureFallback<V> fallback);
181
182
/** Add fallback value for failures */
183
FluentFuture<V> withFallbackValue(V value);
184
185
/** Specify executor for transformations */
186
FluentFuture<V> withExecutor(Executor executor);
187
188
/** Transform result synchronously */
189
<T> FluentFuture<T> transform(Function<? super V, ? extends T> function);
190
191
/** Transform result asynchronously */
192
<T> FluentFuture<T> transform(AsyncFunction<? super V, ? extends T> function);
193
194
/** Transform result lazily (on access) */
195
<T> FluentFuture<T> lazyTransform(Function<? super V, ? extends T> function);
196
}
197
```
198
199
**Usage Example:**
200
201
```java
202
import org.immutables.common.concurrent.FluentFuture;
203
204
// Chain async operations fluently
205
FluentFuture<String> result = userRepository.findById("123")
206
.transform(user -> user.email())
207
.withFallbackValue("unknown@example.com")
208
.addCallback(new FutureCallback<String>() {
209
public void onSuccess(String email) {
210
System.out.println("User email: " + email);
211
}
212
public void onFailure(Throwable t) {
213
System.err.println("Failed to get email: " + t.getMessage());
214
}
215
});
216
```
217
218
## Framework Integrations
219
220
### JDBI Integration
221
222
ResultSetMapperFactory for integrating with JDBI SQL framework.
223
224
```java { .api }
225
/**
226
* JDBI ResultSetMapperFactory for mapping query results to immutable objects.
227
* Register this factory with JDBI to enable automatic mapping of immutable types.
228
*/
229
@Beta
230
public class MapperFactory implements ResultSetMapperFactory {
231
232
/** Check if this factory can handle the specified type */
233
@Override
234
public final boolean accepts(Class type, StatementContext ctx);
235
}
236
```
237
238
**Usage Example:**
239
240
```java
241
import org.immutables.common.jdbi.MapperFactory;
242
243
// Register with JDBI for automatic immutable object mapping
244
DBI dbi = new DBI(dataSource);
245
dbi.registerMapper(new MapperFactory());
246
247
// Query returns immutable objects automatically
248
List<Person> people = dbi.withHandle(handle ->
249
handle.createQuery("SELECT name, age FROM people")
250
.mapTo(Person.class)
251
.list()
252
);
253
```
254
255
### JAX-RS Integration
256
257
MessageBodyReader and MessageBodyWriter for JAX-RS JSON processing.
258
259
```java { .api }
260
/**
261
* JAX-RS MessageBodyReader and MessageBodyWriter providing JSON marshaling
262
* for REST endpoints using generated marshalers.
263
*/
264
@Provider
265
@Consumes(MediaType.APPLICATION_JSON)
266
@Produces(MediaType.APPLICATION_JSON)
267
public class JaxrsMessageBodyProvider implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
268
// Automatic JSON marshaling for JAX-RS endpoints
269
}
270
```
271
272
**Usage Example:**
273
274
```java
275
import org.immutables.common.marshal.JaxrsMessageBodyProvider;
276
277
// Register provider with JAX-RS application
278
@ApplicationPath("/api")
279
public class MyApplication extends Application {
280
@Override
281
public Set<Class<?>> getClasses() {
282
return Set.of(
283
JaxrsMessageBodyProvider.class,
284
UserResource.class
285
);
286
}
287
}
288
289
// REST endpoint automatically handles JSON marshaling
290
@Path("/users")
291
public class UserResource {
292
@POST
293
@Consumes(MediaType.APPLICATION_JSON)
294
@Produces(MediaType.APPLICATION_JSON)
295
public Person createUser(Person person) {
296
// Person automatically unmarshaled from JSON request
297
// Return value automatically marshaled to JSON response
298
return userService.create(person);
299
}
300
}
301
```
302
303
## Advanced Usage Patterns
304
305
### Custom Marshaler Implementation
306
307
```java
308
public class PersonMarshaler extends Marshaler<Person> {
309
310
@Override
311
public Person unmarshalInstance(JsonParser parser) throws IOException {
312
// Custom unmarshaling logic
313
ImmutablePerson.Builder builder = ImmutablePerson.builder();
314
315
while (parser.nextToken() != JsonToken.END_OBJECT) {
316
String fieldName = parser.getCurrentName();
317
parser.nextToken();
318
319
switch (fieldName) {
320
case "name":
321
builder.name(parser.getValueAsString());
322
break;
323
case "age":
324
builder.age(parser.getValueAsInt());
325
break;
326
}
327
}
328
329
return builder.build();
330
}
331
332
@Override
333
public void marshalInstance(JsonGenerator generator, Person person) throws IOException {
334
generator.writeStartObject();
335
generator.writeStringField("name", person.name());
336
generator.writeNumberField("age", person.age());
337
generator.writeEndObject();
338
}
339
340
// Other required methods...
341
}
342
```
343
344
### Repository with Custom Operations
345
346
```java
347
public class UserRepository extends Repositories.Repository<User> {
348
349
public UserRepository(RepositorySetup setup) {
350
super(setup, "users", UserMarshaler.instance());
351
}
352
353
public FluentFuture<Optional<User>> findByEmail(String email) {
354
return findOne(criteria().email(email));
355
}
356
357
public FluentFuture<List<User>> findActiveUsers() {
358
return findAll(criteria().active(true));
359
}
360
361
public FluentFuture<User> updateLastLogin(String userId) {
362
return upsert(
363
criteria().id(userId),
364
modifier().lastLogin(Instant.now())
365
);
366
}
367
}
368
```