0
# Other Utilities
1
2
Additional utilities including event bus, escaping, networking, reflection, and primitive operations that provide specialized functionality for various programming needs.
3
4
## Event Bus (com.google.common.eventbus)
5
6
### EventBus
7
8
Publish-subscribe event handling system that allows decoupled communication between components.
9
10
```java { .api }
11
import com.google.common.eventbus.EventBus;
12
import com.google.common.eventbus.Subscribe;
13
import com.google.common.eventbus.AllowConcurrentEvents;
14
15
// Create event bus
16
EventBus eventBus = new EventBus("main-event-bus");
17
18
// Event classes
19
public class UserLoginEvent {
20
private final String username;
21
private final long timestamp;
22
23
public UserLoginEvent(String username) {
24
this.username = username;
25
this.timestamp = System.currentTimeMillis();
26
}
27
28
// Getters...
29
public String getUsername() { return username; }
30
public long getTimestamp() { return timestamp; }
31
}
32
33
public class OrderPlacedEvent {
34
private final String orderId;
35
private final String userId;
36
private final double amount;
37
38
// Constructor and getters...
39
}
40
41
// Event subscriber
42
public class UserActivityLogger {
43
44
@Subscribe
45
public void handleUserLogin(UserLoginEvent event) {
46
System.out.println("User logged in: " + event.getUsername() +
47
" at " + new Date(event.getTimestamp()));
48
// Log to database, send analytics, etc.
49
}
50
51
@Subscribe
52
@AllowConcurrentEvents // Indicates this method is thread-safe
53
public void handleOrderPlaced(OrderPlacedEvent event) {
54
System.out.println("Order placed: " + event.getOrderId() +
55
" by " + event.getUserId());
56
// Update user activity metrics
57
}
58
}
59
60
// Register subscribers and post events
61
UserActivityLogger logger = new UserActivityLogger();
62
eventBus.register(logger);
63
64
// Post events
65
eventBus.post(new UserLoginEvent("alice"));
66
eventBus.post(new OrderPlacedEvent("ORDER-123", "alice", 99.99));
67
68
// Unregister when no longer needed
69
eventBus.unregister(logger);
70
```
71
72
### AsyncEventBus
73
74
Event bus that dispatches events asynchronously using a provided executor.
75
76
```java { .api }
77
import com.google.common.eventbus.AsyncEventBus;
78
import java.util.concurrent.Executors;
79
80
// Create async event bus with custom executor
81
ExecutorService executor = Executors.newFixedThreadPool(4);
82
AsyncEventBus asyncEventBus = new AsyncEventBus("async-event-bus", executor);
83
84
// Subscriber methods run asynchronously
85
public class EmailNotificationService {
86
87
@Subscribe
88
public void sendWelcomeEmail(UserLoginEvent event) {
89
// This runs asynchronously
90
try {
91
Thread.sleep(2000); // Simulate email sending
92
System.out.println("Welcome email sent to " + event.getUsername());
93
} catch (InterruptedException e) {
94
Thread.currentThread().interrupt();
95
}
96
}
97
}
98
99
EmailNotificationService emailService = new EmailNotificationService();
100
asyncEventBus.register(emailService);
101
102
// This returns immediately, email is sent asynchronously
103
asyncEventBus.post(new UserLoginEvent("bob"));
104
```
105
106
### Dead Events and Error Handling
107
108
Handling events that have no subscribers and subscriber exceptions.
109
110
```java { .api }
111
import com.google.common.eventbus.DeadEvent;
112
import com.google.common.eventbus.SubscriberExceptionHandler;
113
import com.google.common.eventbus.SubscriberExceptionContext;
114
115
// Handle events with no subscribers
116
public class DeadEventLogger {
117
118
@Subscribe
119
public void handleDeadEvent(DeadEvent deadEvent) {
120
Object event = deadEvent.getEvent();
121
EventBus source = deadEvent.getSource();
122
System.out.println("No subscribers for event: " + event.getClass().getSimpleName());
123
}
124
}
125
126
// Custom exception handler
127
SubscriberExceptionHandler exceptionHandler = new SubscriberExceptionHandler() {
128
@Override
129
public void handleException(Throwable exception, SubscriberExceptionContext context) {
130
System.err.println("Exception in subscriber: " + context.getSubscriberMethod());
131
System.err.println("Event: " + context.getEvent());
132
System.err.println("Subscriber: " + context.getSubscriber());
133
exception.printStackTrace();
134
135
// Could log to monitoring system, retry, etc.
136
}
137
};
138
139
// Create event bus with custom exception handler
140
EventBus eventBusWithErrorHandling = new EventBus(exceptionHandler);
141
142
// Register dead event handler
143
DeadEventLogger deadEventLogger = new DeadEventLogger();
144
eventBusWithErrorHandling.register(deadEventLogger);
145
146
// Post event with no subscribers - will be caught as DeadEvent
147
eventBusWithErrorHandling.post("This event has no subscriber");
148
```
149
150
## Networking Utilities (com.google.common.net)
151
152
### HostAndPort
153
154
Immutable representation of network host and port combinations.
155
156
```java { .api }
157
import com.google.common.net.HostAndPort;
158
159
// Parse host:port strings
160
HostAndPort hostPort1 = HostAndPort.fromString("example.com:8080");
161
HostAndPort hostPort2 = HostAndPort.fromString("192.168.1.1:80");
162
HostAndPort hostPort3 = HostAndPort.fromString("[::1]:8080"); // IPv6
163
164
// Create from components
165
HostAndPort hostPort4 = HostAndPort.fromParts("localhost", 3000);
166
HostAndPort hostOnly = HostAndPort.fromHost("example.com"); // No port
167
168
// Access components
169
String host = hostPort1.getHost(); // "example.com"
170
int port = hostPort1.getPort(); // 8080
171
boolean hasPort = hostOnly.hasPort(); // false
172
int portOrDefault = hostOnly.getPortOrDefault(80); // 80
173
174
// With default port
175
HostAndPort withDefault = hostOnly.withDefaultPort(8080);
176
// If hostOnly already has port, returns same instance; otherwise adds default
177
178
// String representation
179
String string = hostPort1.toString(); // "example.com:8080"
180
181
// Validation
182
try {
183
HostAndPort invalid = HostAndPort.fromString("invalid:port:format");
184
} catch (IllegalArgumentException e) {
185
// Handle malformed host:port string
186
}
187
```
188
189
### Internet Domain Names
190
191
Working with domain names and public suffixes.
192
193
```java { .api }
194
import com.google.common.net.InternetDomainName;
195
196
// Parse and validate domain names
197
InternetDomainName domain = InternetDomainName.from("mail.google.com");
198
199
// Validation
200
boolean isValid = InternetDomainName.isValid("example.com"); // true
201
boolean isValid2 = InternetDomainName.isValid("invalid..domain"); // false
202
203
// Domain hierarchy
204
List<String> parts = domain.parts(); // ["mail", "google", "com"]
205
InternetDomainName parent = domain.parent(); // "google.com"
206
InternetDomainName child = domain.child("inbox"); // "inbox.mail.google.com"
207
208
// Public suffix operations (requires public suffix list)
209
boolean isPublicSuffix = domain.isPublicSuffix(); // false
210
InternetDomainName publicSuffix = domain.publicSuffix(); // "com"
211
boolean isTopPrivateDomain = domain.isTopPrivateDomain(); // false ("google.com" would be true)
212
InternetDomainName topPrivate = domain.topPrivateDomain(); // "google.com"
213
214
// Domain relationships
215
InternetDomainName google = InternetDomainName.from("google.com");
216
InternetDomainName gmail = InternetDomainName.from("gmail.com");
217
boolean isUnder = domain.isUnder(google); // true (mail.google.com is under google.com)
218
```
219
220
### IP Address Utilities
221
222
Working with IP addresses and network operations.
223
224
```java { .api }
225
import com.google.common.net.InetAddresses;
226
import java.net.InetAddress;
227
228
// Parse IP address strings
229
InetAddress ipv4 = InetAddresses.forString("192.168.1.1");
230
InetAddress ipv6 = InetAddresses.forString("2001:db8::1");
231
232
// Validation
233
boolean isValid = InetAddresses.isInetAddress("192.168.1.1"); // true
234
boolean isValid2 = InetAddresses.isInetAddress("300.1.1.1"); // false
235
236
// Convert to string representation
237
String canonical = InetAddresses.toAddrString(ipv4); // "192.168.1.1"
238
String ipv6String = InetAddresses.toAddrString(ipv6); // "2001:db8::1"
239
240
// IP address manipulation
241
InetAddress incremented = InetAddresses.increment(ipv4); // 192.168.1.2
242
InetAddress decremented = InetAddresses.decrement(ipv4); // 192.168.1.0
243
244
// Check bounds
245
boolean isMax = InetAddresses.isMaximum(ipv4); // false
246
247
// IPv4/IPv6 conversions
248
InetAddress ipv4Addr = InetAddresses.forString("192.168.1.1");
249
InetAddress coerced = InetAddresses.getCoercedIPv4Address(ipv4Addr); // Same address
250
251
// Extract embedded IPv4 from IPv6 (for IPv4-mapped IPv6 addresses)
252
InetAddress embedded = InetAddresses.getEmbeddedIPv4ClientAddress(
253
InetAddresses.forString("::ffff:192.168.1.1")); // 192.168.1.1
254
```
255
256
### Media Types
257
258
Working with MIME types and media type parsing.
259
260
```java { .api }
261
import com.google.common.net.MediaType;
262
import java.nio.charset.StandardCharsets;
263
264
// Parse media types
265
MediaType json = MediaType.parse("application/json");
266
MediaType html = MediaType.parse("text/html; charset=utf-8");
267
MediaType pdf = MediaType.parse("application/pdf");
268
269
// Create media types
270
MediaType plainText = MediaType.create("text", "plain");
271
MediaType xmlUtf8 = MediaType.create("application", "xml")
272
.withCharset(StandardCharsets.UTF_8);
273
274
// Access components
275
String type = json.type(); // "application"
276
String subtype = json.subtype(); // "json"
277
String fullType = json.toString(); // "application/json"
278
279
// Parameters
280
Optional<Charset> charset = html.charset(); // Optional[UTF-8]
281
ImmutableListMultimap<String, String> parameters = html.parameters();
282
283
// Modify media types
284
MediaType withCharset = json.withCharset(StandardCharsets.UTF_8);
285
MediaType withParameter = json.withParameter("boundary", "----WebKitFormBoundary");
286
MediaType withoutParams = html.withoutParameters();
287
288
// Common media types (constants)
289
MediaType jpeg = MediaType.JPEG; // image/jpeg
290
MediaType css = MediaType.CSS; // text/css
291
MediaType javascript = MediaType.JAVASCRIPT_UTF_8; // application/javascript; charset=utf-8
292
293
// Type matching
294
boolean isJson = MediaType.JSON_UTF_8.is(MediaType.parse("application/json")); // true
295
boolean isText = MediaType.ANY_TEXT_TYPE.is(MediaType.PLAIN_TEXT_UTF_8); // true
296
```
297
298
## Escaping Utilities (com.google.common.escape)
299
300
### HTML and XML Escaping
301
302
Safe escaping for HTML and XML content.
303
304
```java { .api }
305
import com.google.common.html.HtmlEscapers;
306
import com.google.common.xml.XmlEscapers;
307
import com.google.common.escape.Escaper;
308
309
// HTML escaping
310
Escaper htmlEscaper = HtmlEscapers.htmlEscaper();
311
String escaped = htmlEscaper.escape("<script>alert('XSS')</script>");
312
// Result: "<script>alert('XSS')</script>"
313
314
String userInput = "Tom & Jerry's \"Adventures\"";
315
String safeHtml = htmlEscaper.escape(userInput);
316
// Result: "Tom & Jerry's "Adventures""
317
318
// XML escaping
319
Escaper xmlContentEscaper = XmlEscapers.xmlContentEscaper();
320
Escaper xmlAttributeEscaper = XmlEscapers.xmlAttributeEscaper();
321
322
String xmlContent = xmlContentEscaper.escape("Data with <tags> & \"quotes\"");
323
// Result: "Data with <tags> & \"quotes\""
324
325
String xmlAttr = xmlAttributeEscaper.escape("Value with \"quotes\" & <brackets>");
326
// Result: "Value with "quotes" & <brackets>"
327
328
// Usage in templates
329
public String generateHtml(String title, String content) {
330
return "<html><head><title>" + htmlEscaper.escape(title) + "</title></head>" +
331
"<body>" + htmlEscaper.escape(content) + "</body></html>";
332
}
333
```
334
335
### Custom Escapers
336
337
Building custom escapers for specific needs.
338
339
```java { .api }
340
import com.google.common.escape.Escapers;
341
import com.google.common.escape.CharEscaperBuilder;
342
343
// Build custom escaper
344
Escaper customEscaper = Escapers.builder()
345
.addEscape('\'', "\\'") // Escape single quotes
346
.addEscape('\"', "\\\"") // Escape double quotes
347
.addEscape('\\', "\\\\") // Escape backslashes
348
.addEscape('\n', "\\n") // Escape newlines
349
.addEscape('\t', "\\t") // Escape tabs
350
.toEscaper();
351
352
String input = "String with 'quotes' and \"escapes\"\nand newlines";
353
String escaped = customEscaper.escape(input);
354
355
// CSV escaper example
356
Escaper csvEscaper = Escapers.builder()
357
.addEscape('\"', "\"\"") // Double quote escaping for CSV
358
.toEscaper();
359
360
public String escapeCsvField(String field) {
361
if (field.contains("\"") || field.contains(",") || field.contains("\n")) {
362
return "\"" + csvEscaper.escape(field) + "\"";
363
}
364
return field;
365
}
366
367
// URL component escaper (for path segments, not full URLs)
368
Escaper urlEscaper = Escapers.builder()
369
.addEscape(' ', "%20")
370
.addEscape('!', "%21")
371
.addEscape('\"', "%22")
372
.addEscape('#', "%23")
373
// Add more as needed
374
.toEscaper();
375
```
376
377
## Primitive Utilities (com.google.common.primitives)
378
379
### Primitive Array Operations
380
381
Utilities for working with primitive arrays and their wrapper types.
382
383
```java { .api }
384
import com.google.common.primitives.Ints;
385
import com.google.common.primitives.Longs;
386
import com.google.common.primitives.Doubles;
387
import com.google.common.primitives.Booleans;
388
389
// Array to List conversions
390
int[] intArray = {1, 2, 3, 4, 5};
391
List<Integer> intList = Ints.asList(intArray);
392
393
// List to array conversions
394
List<Integer> numbers = Arrays.asList(10, 20, 30);
395
int[] backToArray = Ints.toArray(numbers);
396
397
// Array operations
398
boolean contains = Ints.contains(intArray, 3); // true
399
int index = Ints.indexOf(intArray, 4); // 3
400
int lastIndex = Ints.lastIndexOf(intArray, 2); // 1
401
402
// Min/Max operations
403
int min = Ints.min(intArray); // 1
404
int max = Ints.max(intArray); // 5
405
406
// Joining arrays as strings
407
String joined = Ints.join(", ", intArray); // "1, 2, 3, 4, 5"
408
409
// Lexicographical comparison
410
Comparator<int[]> comparator = Ints.lexicographicalComparator();
411
int comparison = comparator.compare(new int[]{1, 2}, new int[]{1, 3}); // -1
412
413
// Similar operations for other primitive types
414
long[] longArray = {1L, 2L, 3L};
415
List<Long> longList = Longs.asList(longArray);
416
long maxLong = Longs.max(longArray);
417
418
double[] doubleArray = {1.1, 2.2, 3.3};
419
boolean isFinite = Doubles.isFinite(2.2); // true (not NaN or infinity)
420
421
boolean[] boolArray = {true, false, true, true};
422
int trueCount = Booleans.countTrue(boolArray); // 3
423
```
424
425
### Parsing and Conversion
426
427
Safe parsing of strings to primitive types.
428
429
```java { .api }
430
// Safe parsing (returns null for invalid input)
431
Integer parsed = Ints.tryParse("123"); // 123
432
Integer invalid = Ints.tryParse("abc"); // null
433
Integer overflow = Ints.tryParse("999999999999999999"); // null (overflow)
434
435
Long longParsed = Longs.tryParse("123456789");
436
Double doubleParsed = Doubles.tryParse("3.14159");
437
438
// String converters (for use with Functions)
439
Function<String, Integer> intConverter = Ints.stringConverter();
440
Function<Integer, String> intToString = intConverter.reverse();
441
442
// Usage with collections
443
List<String> stringNumbers = Arrays.asList("1", "2", "3", "invalid", "5");
444
List<Integer> validNumbers = stringNumbers.stream()
445
.map(Ints::tryParse)
446
.filter(Objects::nonNull)
447
.collect(Collectors.toList()); // [1, 2, 3, 5]
448
```
449
450
### Unsigned Arithmetic
451
452
Working with unsigned integer values.
453
454
```java { .api }
455
import com.google.common.primitives.UnsignedInteger;
456
import com.google.common.primitives.UnsignedLong;
457
import com.google.common.primitives.UnsignedInts;
458
import com.google.common.primitives.UnsignedLongs;
459
460
// Unsigned integers
461
UnsignedInteger uint1 = UnsignedInteger.valueOf(0x80000000L); // Large positive value
462
UnsignedInteger uint2 = UnsignedInteger.valueOf("4294967295"); // Max unsigned 32-bit
463
464
// Arithmetic operations
465
UnsignedInteger sum = uint1.plus(uint2);
466
UnsignedInteger difference = uint1.minus(uint2);
467
UnsignedInteger product = uint1.times(UnsignedInteger.valueOf(2));
468
UnsignedInteger quotient = uint1.dividedBy(UnsignedInteger.valueOf(2));
469
470
// Comparison
471
int comparison = uint1.compareTo(uint2);
472
473
// Conversion
474
long asLong = uint1.longValue(); // As signed long
475
String asString = uint1.toString();
476
477
// Unsigned longs (for values larger than signed long max)
478
UnsignedLong ulong1 = UnsignedLong.valueOf(new BigInteger("18446744073709551615")); // Max unsigned 64-bit
479
UnsignedLong ulong2 = UnsignedLong.valueOf("9223372036854775808"); // Just over signed long max
480
481
// Static utility methods for unsigned operations
482
int unsignedComparison = UnsignedInts.compare(0x80000000, 0x7FFFFFFF); // 1 (first is larger unsigned)
483
int signedComparison = Integer.compare(0x80000000, 0x7FFFFFFF); // -1 (first is negative signed)
484
485
long unsignedDivision = UnsignedInts.divide(0x80000000, 2); // Correct unsigned division
486
String unsignedString = UnsignedInts.toString(0x80000000); // "2147483648"
487
488
// Parsing unsigned values
489
int parsedUnsigned = UnsignedInts.parseUnsignedInt("4294967295"); // Max unsigned 32-bit
490
long parsedUnsignedLong = UnsignedLongs.parseUnsignedLong("18446744073709551615");
491
```
492
493
## Reflection Utilities (com.google.common.reflect)
494
495
### TypeToken
496
497
Type-safe reflection for generic types.
498
499
```java { .api }
500
import com.google.common.reflect.TypeToken;
501
import java.lang.reflect.Type;
502
503
// Capture generic types at runtime
504
TypeToken<List<String>> stringListToken = new TypeToken<List<String>>() {};
505
TypeToken<Map<String, Integer>> mapToken = new TypeToken<Map<String, Integer>>() {};
506
507
// Get type information
508
Type listType = stringListToken.getType(); // java.util.List<java.lang.String>
509
Class<? super List<String>> rawType = stringListToken.getRawType(); // class java.util.List
510
511
// Type relationships
512
TypeToken<ArrayList<String>> arrayListToken = new TypeToken<ArrayList<String>>() {};
513
boolean isSubtype = arrayListToken.isSubtypeOf(stringListToken); // true
514
515
TypeToken<List<Object>> objectListToken = new TypeToken<List<Object>>() {};
516
boolean isSuper = objectListToken.isSupertypeOf(stringListToken); // true
517
518
// Resolve generic types in inheritance hierarchy
519
class StringList extends ArrayList<String> {}
520
TypeToken<StringList> stringListSubclass = TypeToken.of(StringList.class);
521
TypeToken<?> resolvedSupertype = stringListSubclass.getSupertype(List.class);
522
// Resolves to List<String>
523
524
// Working with method return types and parameters
525
public class GenericService<T> {
526
public List<T> getItems() { return null; }
527
public void setItems(List<T> items) {}
528
}
529
530
TypeToken<GenericService<String>> serviceToken = new TypeToken<GenericService<String>>() {};
531
Method getItemsMethod = GenericService.class.getMethod("getItems");
532
TypeToken<?> returnType = serviceToken.resolveType(getItemsMethod.getGenericReturnType());
533
// Resolves to List<String>
534
```
535
536
### ClassPath Scanning
537
538
Scanning the classpath to find classes and resources.
539
540
```java { .api }
541
import com.google.common.reflect.ClassPath;
542
import java.util.Set;
543
544
// Scan classpath
545
ClassPath classPath = ClassPath.from(Thread.currentThread().getContextClassLoader());
546
547
// Find all classes
548
Set<ClassPath.ClassInfo> allClasses = classPath.getAllClasses();
549
550
// Find classes in specific package
551
String packageName = "com.example.services";
552
Set<ClassPath.ClassInfo> packageClasses = classPath.getTopLevelClasses(packageName);
553
554
// Find classes recursively in package hierarchy
555
Set<ClassPath.ClassInfo> recursiveClasses = classPath.getTopLevelClassesRecursive(packageName);
556
557
// Load and filter classes
558
List<Class<?>> serviceClasses = packageClasses.stream()
559
.map(ClassPath.ClassInfo::load)
560
.filter(clazz -> clazz.getSimpleName().endsWith("Service"))
561
.collect(Collectors.toList());
562
563
// Find classes by annotation
564
List<Class<?>> annotatedClasses = allClasses.stream()
565
.map(ClassPath.ClassInfo::load)
566
.filter(clazz -> clazz.isAnnotationPresent(Component.class))
567
.collect(Collectors.toList());
568
569
// Resource scanning
570
Set<ClassPath.ResourceInfo> resources = classPath.getResources();
571
Optional<ClassPath.ResourceInfo> configResource = resources.stream()
572
.filter(resource -> resource.getResourceName().endsWith("application.properties"))
573
.findFirst();
574
```
575
576
### Invokable Wrapper
577
578
Type-safe wrapper for Method and Constructor with better generic support.
579
580
```java { .api }
581
import com.google.common.reflect.Invokable;
582
import com.google.common.reflect.Parameter;
583
import java.lang.reflect.Method;
584
585
// Wrap methods
586
Method method = String.class.getMethod("substring", int.class, int.class);
587
Invokable<String, String> substringInvokable = Invokable.from(method);
588
589
// Type-safe invocation
590
String result = substringInvokable.invoke("Hello World", 0, 5); // "Hello"
591
592
// Generic type information
593
TypeToken<String> returnType = substringInvokable.getReturnType();
594
List<Parameter> parameters = substringInvokable.getParameters();
595
596
// Parameter information
597
Parameter firstParam = parameters.get(0);
598
TypeToken<?> paramType = firstParam.getType(); // TypeToken for int
599
boolean isAnnotated = firstParam.isAnnotationPresent(SomeAnnotation.class);
600
601
// Constructor wrapping
602
Constructor<ArrayList> constructor = ArrayList.class.getConstructor(int.class);
603
Invokable<Void, ArrayList> constructorInvokable = Invokable.from(constructor);
604
ArrayList<String> list = constructorInvokable.invoke(null, 10); // Initial capacity 10
605
606
// Exception types
607
ImmutableList<TypeToken<? extends Throwable>> exceptionTypes =
608
substringInvokable.getExceptionTypes();
609
```
610
611
## Practical Applications
612
613
Real-world examples combining various utilities.
614
615
```java { .api }
616
// Event-driven application architecture
617
public class OrderProcessingSystem {
618
private final EventBus eventBus;
619
private final PaymentService paymentService;
620
private final InventoryService inventoryService;
621
private final NotificationService notificationService;
622
623
public OrderProcessingSystem() {
624
this.eventBus = new EventBus("order-processing");
625
this.paymentService = new PaymentService();
626
this.inventoryService = new InventoryService();
627
this.notificationService = new NotificationService();
628
629
// Register all services as event subscribers
630
eventBus.register(paymentService);
631
eventBus.register(inventoryService);
632
eventBus.register(notificationService);
633
}
634
635
public void processOrder(Order order) {
636
// Validate order
637
if (order.getAmount() <= 0) {
638
eventBus.post(new OrderRejectedEvent(order, "Invalid amount"));
639
return;
640
}
641
642
// Post order received event
643
eventBus.post(new OrderReceivedEvent(order));
644
}
645
646
public static class OrderReceivedEvent {
647
private final Order order;
648
public OrderReceivedEvent(Order order) { this.order = order; }
649
public Order getOrder() { return order; }
650
}
651
652
public static class OrderRejectedEvent {
653
private final Order order;
654
private final String reason;
655
public OrderRejectedEvent(Order order, String reason) {
656
this.order = order;
657
this.reason = reason;
658
}
659
// Getters...
660
}
661
}
662
663
// Web API parameter parsing
664
public class ApiParameterParser {
665
666
public static Optional<Integer> parseIntParameter(String value) {
667
return Optional.fromNullable(Ints.tryParse(value));
668
}
669
670
public static List<Integer> parseIntList(String value) {
671
if (Strings.isNullOrEmpty(value)) {
672
return Collections.emptyList();
673
}
674
675
return Splitter.on(',')
676
.trimResults()
677
.omitEmptyStrings()
678
.splitToList(value)
679
.stream()
680
.map(Ints::tryParse)
681
.filter(Objects::nonNull)
682
.collect(Collectors.toList());
683
}
684
685
public static String sanitizeUserInput(String input) {
686
if (input == null) return "";
687
688
// Escape HTML to prevent XSS
689
return HtmlEscapers.htmlEscaper().escape(input.trim());
690
}
691
}
692
693
// Configuration management with type safety
694
public class ConfigurationManager {
695
private final Map<String, String> properties;
696
private final Escaper propertyEscaper;
697
698
public ConfigurationManager(Properties props) {
699
this.properties = Maps.fromProperties(props);
700
this.propertyEscaper = Escapers.builder()
701
.addEscape('\\', "\\\\")
702
.addEscape('=', "\\=")
703
.addEscape(':', "\\:")
704
.toEscaper();
705
}
706
707
public Optional<String> getString(String key) {
708
return Optional.fromNullable(properties.get(key));
709
}
710
711
public Optional<Integer> getInt(String key) {
712
return getString(key).transform(Ints::tryParse);
713
}
714
715
public Optional<Boolean> getBoolean(String key) {
716
return getString(key).transform(Boolean::parseBoolean);
717
}
718
719
public List<String> getStringList(String key) {
720
return getString(key)
721
.transform(value -> Splitter.on(',').trimResults().splitToList(value))
722
.or(Collections.emptyList());
723
}
724
725
public HostAndPort getHostAndPort(String key) {
726
return getString(key)
727
.transform(HostAndPort::fromString)
728
.orNull();
729
}
730
}
731
732
// Service discovery with networking utilities
733
public class ServiceRegistry {
734
private final Map<String, Set<HostAndPort>> services = new ConcurrentHashMap<>();
735
736
public void registerService(String serviceName, String hostPort) {
737
try {
738
HostAndPort parsed = HostAndPort.fromString(hostPort);
739
services.computeIfAbsent(serviceName, k -> ConcurrentHashMap.newKeySet())
740
.add(parsed);
741
} catch (IllegalArgumentException e) {
742
throw new IllegalArgumentException("Invalid host:port format: " + hostPort, e);
743
}
744
}
745
746
public Optional<HostAndPort> getServiceEndpoint(String serviceName) {
747
Set<HostAndPort> endpoints = services.get(serviceName);
748
if (endpoints == null || endpoints.isEmpty()) {
749
return Optional.absent();
750
}
751
752
// Simple round-robin selection
753
return Optional.of(endpoints.iterator().next());
754
}
755
756
public boolean isValidServiceEndpoint(String hostPort) {
757
try {
758
HostAndPort.fromString(hostPort);
759
return true;
760
} catch (IllegalArgumentException e) {
761
return false;
762
}
763
}
764
}
765
```
766
767
These utilities provide essential functionality for building robust applications with proper input validation, event-driven architectures, network communication, and type-safe operations while maintaining clean, readable code.