0
# Utility Classes
1
2
Collection of utility classes for common operations including file handling, string manipulation, time parsing, hash calculations, and system detection.
3
4
## Capabilities
5
6
### File and Directory Utilities
7
8
Utilities for file system operations and directory management.
9
10
```java { .api }
11
/**
12
* File system utilities
13
*/
14
public final class FileUtils {
15
/**
16
* Ensure directory exists, creating it if necessary
17
*/
18
public static void ensureDirectoryExists(File directory) throws IOException;
19
20
/**
21
* Delete directory contents recursively
22
*/
23
public static void deleteDirectoryContents(File directory) throws IOException;
24
25
/**
26
* Copy file from source to destination
27
*/
28
public static void copy(File source, File destination) throws IOException;
29
30
/**
31
* Move file from source to destination
32
*/
33
public static void move(File source, File destination) throws IOException;
34
35
/**
36
* Get file extension
37
*/
38
public static String getExtension(File file);
39
40
/**
41
* Check if file is readable
42
*/
43
public static boolean isReadable(File file);
44
45
/**
46
* Get file size in bytes
47
*/
48
public static long getFileSize(File file);
49
}
50
51
/**
52
* Directory operation utilities
53
*/
54
public class DirUtils {
55
/**
56
* Create temporary directory
57
*/
58
public static File createTempDir(String prefix) throws IOException;
59
60
/**
61
* List files in directory with filter
62
*/
63
public static List<File> listFiles(File directory, FileFilter filter);
64
65
/**
66
* Get directory size recursively
67
*/
68
public static long getDirectorySize(File directory);
69
70
/**
71
* Clean directory by removing old files
72
*/
73
public static void cleanDirectory(File directory, long maxAgeMs);
74
}
75
```
76
77
### String Manipulation Utilities
78
79
Utilities for string processing and manipulation.
80
81
```java { .api }
82
/**
83
* String manipulation utilities
84
*/
85
public class StringUtils {
86
/**
87
* Check if string is null or empty
88
*/
89
public static boolean isEmpty(String str);
90
91
/**
92
* Check if string is not null and not empty
93
*/
94
public static boolean isNotEmpty(String str);
95
96
/**
97
* Join array of strings with delimiter
98
*/
99
public static String join(String[] parts, String delimiter);
100
101
/**
102
* Join collection of strings with delimiter
103
*/
104
public static String join(Collection<String> parts, String delimiter);
105
106
/**
107
* Split string and trim whitespace from parts
108
*/
109
public static String[] splitAndTrim(String str, String delimiter);
110
111
/**
112
* Escape special characters for regex
113
*/
114
public static String escapeRegex(String str);
115
116
/**
117
* Convert camelCase to snake_case
118
*/
119
public static String camelToSnake(String camelCase);
120
121
/**
122
* Convert snake_case to camelCase
123
*/
124
public static String snakeToCamel(String snakeCase);
125
}
126
```
127
128
### Time and Date Utilities
129
130
Utilities for time parsing, calculation, and formatting.
131
132
```java { .api }
133
/**
134
* Time expression parser for relative time calculations
135
*/
136
public class TimeMathParser {
137
/**
138
* Parse time math expression to milliseconds
139
* Examples: "5m", "2h", "1d", "now-1h", "now+30m"
140
*/
141
public static long parseTimeInMs(String timeMath) throws IllegalArgumentException;
142
143
/**
144
* Parse time math expression to seconds
145
*/
146
public static long parseTimeInSeconds(String timeMath) throws IllegalArgumentException;
147
148
/**
149
* Parse relative time from base timestamp
150
*/
151
public static long parseRelativeTime(String timeMath, long baseTime) throws IllegalArgumentException;
152
153
/**
154
* Check if string is a valid time expression
155
*/
156
public static boolean isValidTimeExpression(String expr);
157
}
158
159
/**
160
* Time provider interface for testability
161
*/
162
public interface TimeProvider {
163
/**
164
* Get current time in milliseconds
165
*/
166
long currentTimeMillis();
167
}
168
169
/**
170
* System time provider (default implementation)
171
*/
172
public class SystemTimeProvider implements TimeProvider {
173
@Override
174
public long currentTimeMillis();
175
}
176
```
177
178
### Hash and Checksum Utilities
179
180
Utilities for hash calculations and data integrity checks.
181
182
```java { .api }
183
/**
184
* Hash calculation utilities
185
*/
186
public class HashUtils {
187
/**
188
* Calculate MD5 hash of byte array
189
*/
190
public static String md5(byte[] data);
191
192
/**
193
* Calculate MD5 hash of string
194
*/
195
public static String md5(String data);
196
197
/**
198
* Calculate SHA-1 hash of byte array
199
*/
200
public static String sha1(byte[] data);
201
202
/**
203
* Calculate SHA-256 hash of byte array
204
*/
205
public static String sha256(byte[] data);
206
207
/**
208
* Calculate hash of file
209
*/
210
public static String fileHash(File file, String algorithm) throws IOException;
211
}
212
213
/**
214
* Checksum calculation utilities
215
*/
216
public class Checksums {
217
/**
218
* Calculate CRC32 checksum
219
*/
220
public static long crc32(byte[] data);
221
222
/**
223
* Calculate CRC32 checksum of file
224
*/
225
public static long crc32(File file) throws IOException;
226
227
/**
228
* Calculate Adler32 checksum
229
*/
230
public static long adler32(byte[] data);
231
232
/**
233
* Verify checksum matches expected value
234
*/
235
public static boolean verify(byte[] data, long expectedChecksum, String algorithm);
236
}
237
```
238
239
### System Detection Utilities
240
241
Utilities for detecting system properties and capabilities.
242
243
```java { .api }
244
/**
245
* Operating system detection utility
246
*/
247
public class OSDetector {
248
/**
249
* Check if running on Windows
250
*/
251
public static boolean isWindows();
252
253
/**
254
* Check if running on Linux
255
*/
256
public static boolean isLinux();
257
258
/**
259
* Check if running on macOS
260
*/
261
public static boolean isMac();
262
263
/**
264
* Get operating system name
265
*/
266
public static String getOSName();
267
268
/**
269
* Get operating system architecture
270
*/
271
public static String getArchitecture();
272
273
/**
274
* Check if running on 64-bit architecture
275
*/
276
public static boolean is64Bit();
277
}
278
279
/**
280
* Port availability detection utility
281
*/
282
public class PortDetector {
283
/**
284
* Check if port is available
285
*/
286
public static boolean isPortAvailable(int port);
287
288
/**
289
* Check if port is available on specific host
290
*/
291
public static boolean isPortAvailable(String host, int port);
292
293
/**
294
* Find next available port starting from given port
295
*/
296
public static int findAvailablePort(int startPort);
297
298
/**
299
* Find N available ports
300
*/
301
public static List<Integer> findAvailablePorts(int count, int startPort);
302
}
303
304
/**
305
* Project information utilities
306
*/
307
public class ProjectInfo {
308
/**
309
* Get project version from manifest
310
*/
311
public static String getVersion();
312
313
/**
314
* Get project version for specific class
315
*/
316
public static String getVersion(Class<?> clazz);
317
318
/**
319
* Get build timestamp
320
*/
321
public static String getBuildTime();
322
323
/**
324
* Get git commit hash
325
*/
326
public static String getGitCommit();
327
}
328
```
329
330
### Run ID Generation
331
332
Utilities for generating unique program run identifiers using time-based UUIDs.
333
334
```java { .api }
335
/**
336
* Utilities for generating unique run IDs for CDAP program runs
337
*/
338
public final class RunIds {
339
/**
340
* Generate a new run ID based on current time
341
* @return Time-based UUID run ID
342
*/
343
public static RunId generate();
344
345
/**
346
* Generate run ID for specific time (testing purposes)
347
* @param timeMillis Timestamp in milliseconds
348
* @return Time-based UUID run ID for the specified time
349
*/
350
public static RunId generate(long timeMillis);
351
352
/**
353
* Convert string representation to RunId
354
* @param id String representation of UUID
355
* @return RunId object
356
*/
357
public static RunId fromString(String id);
358
359
/**
360
* Extract timestamp from run ID
361
* @param runId The run ID to extract time from
362
* @param timeUnit Time unit for the result
363
* @return Timestamp in specified time unit
364
*/
365
public static long getTime(RunId runId, TimeUnit timeUnit);
366
367
/**
368
* Extract timestamp from run ID string
369
* @param runId The run ID string to extract time from
370
* @param timeUnit Time unit for the result
371
* @return Timestamp in specified time unit
372
*/
373
public static long getTime(String runId, TimeUnit timeUnit);
374
375
/**
376
* JSON codec for RunId serialization/deserialization
377
*/
378
public static class RunIdCodec implements JsonSerializer<RunId>, JsonDeserializer<RunId> {
379
@Override
380
public JsonElement serialize(RunId src, Type typeOfSrc, JsonSerializationContext context);
381
382
@Override
383
public RunId deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context);
384
}
385
}
386
```
387
388
**Usage Examples:**
389
390
```java
391
import io.cdap.cdap.common.app.RunIds;
392
import java.util.concurrent.TimeUnit;
393
394
// Generate run IDs
395
RunId currentRunId = RunIds.generate();
396
System.out.println("Current run ID: " + currentRunId.getId());
397
398
// Generate run ID for specific time (useful for testing)
399
long specificTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1);
400
RunId historicRunId = RunIds.generate(specificTime);
401
402
// Convert between string and RunId
403
String runIdString = currentRunId.getId();
404
RunId parsedRunId = RunIds.fromString(runIdString);
405
406
// Extract timestamps from run IDs
407
long runTimeMs = RunIds.getTime(currentRunId, TimeUnit.MILLISECONDS);
408
long runTimeSeconds = RunIds.getTime(runIdString, TimeUnit.SECONDS);
409
410
System.out.println("Run started at: " + new Date(runTimeMs));
411
System.out.println("Run started " +
412
(System.currentTimeMillis() - runTimeMs) / 1000 + " seconds ago");
413
```
414
415
### Task Execution Utilities
416
417
Utilities for task execution and coordination.
418
419
```java { .api }
420
/**
421
* Task execution utilities
422
*/
423
public class Tasks {
424
/**
425
* Execute task with timeout
426
*/
427
public static <T> T execute(Callable<T> task, long timeout, TimeUnit unit)
428
throws Exception, TimeoutException;
429
430
/**
431
* Execute runnable with timeout
432
*/
433
public static void execute(Runnable task, long timeout, TimeUnit unit)
434
throws TimeoutException;
435
436
/**
437
* Execute task with retry
438
*/
439
public static <T> T executeWithRetry(Callable<T> task, int maxAttempts,
440
long retryDelay, TimeUnit unit) throws Exception;
441
442
/**
443
* Execute multiple tasks in parallel
444
*/
445
public static <T> List<T> executeParallel(List<Callable<T>> tasks,
446
ExecutorService executor) throws Exception;
447
448
/**
449
* Execute task periodically
450
*/
451
public static ScheduledFuture<?> executePeriodically(Runnable task,
452
long initialDelay, long period,
453
TimeUnit unit,
454
ScheduledExecutorService executor);
455
}
456
```
457
458
**Usage Examples:**
459
460
```java
461
import io.cdap.cdap.common.utils.*;
462
import java.util.concurrent.*;
463
464
// File operations
465
public class FileOperations {
466
public void setupWorkspace(String workspaceRoot) throws IOException {
467
File workspace = new File(workspaceRoot);
468
469
// Ensure workspace directory exists
470
FileUtils.ensureDirectoryExists(workspace);
471
472
// Create subdirectories
473
File dataDir = new File(workspace, "data");
474
File logsDir = new File(workspace, "logs");
475
File tempDir = new File(workspace, "temp");
476
477
FileUtils.ensureDirectoryExists(dataDir);
478
FileUtils.ensureDirectoryExists(logsDir);
479
FileUtils.ensureDirectoryExists(tempDir);
480
481
// Clean old temporary files (older than 1 hour)
482
DirUtils.cleanDirectory(tempDir, TimeUnit.HOURS.toMillis(1));
483
484
System.out.println("Workspace setup complete. Size: " +
485
DirUtils.getDirectorySize(workspace) + " bytes");
486
}
487
488
public void processFiles(File inputDir, File outputDir) throws IOException {
489
// List only .txt files
490
List<File> textFiles = DirUtils.listFiles(inputDir,
491
file -> file.getName().endsWith(".txt"));
492
493
for (File file : textFiles) {
494
if (FileUtils.isReadable(file)) {
495
File destination = new File(outputDir,
496
"processed_" + file.getName());
497
FileUtils.copy(file, destination);
498
499
System.out.println("Processed: " + file.getName() +
500
" (" + FileUtils.getFileSize(file) + " bytes)");
501
}
502
}
503
}
504
}
505
506
// String processing
507
public class DataProcessor {
508
public void processConfigValues(Properties config) {
509
for (String key : config.stringPropertyNames()) {
510
String value = config.getProperty(key);
511
512
if (StringUtils.isEmpty(value)) {
513
System.out.println("Empty value for key: " + key);
514
continue;
515
}
516
517
// Convert configuration keys from camelCase to snake_case
518
String normalizedKey = StringUtils.camelToSnake(key);
519
520
// Split comma-separated values and trim
521
if (value.contains(",")) {
522
String[] parts = StringUtils.splitAndTrim(value, ",");
523
String joined = StringUtils.join(parts, " | ");
524
System.out.println(normalizedKey + " = " + joined);
525
}
526
}
527
}
528
}
529
530
// Time-based operations
531
public class TimeBasedService {
532
private final TimeProvider timeProvider = new SystemTimeProvider();
533
534
public void scheduleCleanup(String retentionPeriod) {
535
try {
536
// Parse retention period (e.g., "7d", "24h", "30m")
537
long retentionMs = TimeMathParser.parseTimeInMs(retentionPeriod);
538
long cutoffTime = timeProvider.currentTimeMillis() - retentionMs;
539
540
System.out.println("Cleaning up files older than: " +
541
new Date(cutoffTime));
542
543
// Cleanup logic...
544
cleanupOldFiles(cutoffTime);
545
546
} catch (IllegalArgumentException e) {
547
System.err.println("Invalid retention period: " + retentionPeriod);
548
}
549
}
550
551
public void scheduleRelativeExecution(String timeExpression) {
552
try {
553
// Parse relative time (e.g., "now+5m", "now-1h")
554
long executionTime = TimeMathParser.parseTimeInMs(timeExpression);
555
long delay = executionTime - timeProvider.currentTimeMillis();
556
557
if (delay > 0) {
558
// Schedule future execution
559
scheduleExecution(delay);
560
} else {
561
System.out.println("Time expression refers to past: " + timeExpression);
562
}
563
564
} catch (IllegalArgumentException e) {
565
System.err.println("Invalid time expression: " + timeExpression);
566
}
567
}
568
569
private void cleanupOldFiles(long cutoffTime) {
570
// Implementation...
571
}
572
573
private void scheduleExecution(long delay) {
574
// Implementation...
575
}
576
}
577
578
// System detection and adaptation
579
public class PlatformService {
580
public void configurePlatformSpecific() {
581
System.out.println("Platform: " + OSDetector.getOSName() +
582
" (" + OSDetector.getArchitecture() + ")");
583
584
if (OSDetector.isWindows()) {
585
configureWindows();
586
} else if (OSDetector.isLinux()) {
587
configureLinux();
588
} else if (OSDetector.isMac()) {
589
configureMac();
590
}
591
592
// Find available ports for services
593
List<Integer> ports = PortDetector.findAvailablePorts(3, 8080);
594
System.out.println("Available ports: " + ports);
595
}
596
597
public void validateSystemRequirements() {
598
if (!OSDetector.is64Bit()) {
599
throw new RuntimeException("64-bit architecture required");
600
}
601
602
if (!PortDetector.isPortAvailable(8080)) {
603
System.out.println("Port 8080 not available, finding alternative...");
604
int alternativePort = PortDetector.findAvailablePort(8081);
605
System.out.println("Using port: " + alternativePort);
606
}
607
}
608
609
private void configureWindows() { /* Windows-specific config */ }
610
private void configureLinux() { /* Linux-specific config */ }
611
private void configureMac() { /* macOS-specific config */ }
612
}
613
614
// Task execution patterns
615
public class TaskExecutionService {
616
private final ExecutorService executor = Executors.newFixedThreadPool(10);
617
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
618
619
public void processWithTimeout() {
620
try {
621
String result = Tasks.execute(() -> {
622
// Long-running operation
623
Thread.sleep(5000);
624
return "Operation completed";
625
}, 10, TimeUnit.SECONDS);
626
627
System.out.println("Result: " + result);
628
629
} catch (TimeoutException e) {
630
System.err.println("Operation timed out");
631
} catch (Exception e) {
632
System.err.println("Operation failed: " + e.getMessage());
633
}
634
}
635
636
public void processWithRetry() {
637
try {
638
String result = Tasks.executeWithRetry(() -> {
639
// Operation that might fail
640
if (Math.random() < 0.7) {
641
throw new RuntimeException("Random failure");
642
}
643
return "Success";
644
}, 3, 1000, TimeUnit.MILLISECONDS);
645
646
System.out.println("Result after retries: " + result);
647
648
} catch (Exception e) {
649
System.err.println("All retry attempts failed: " + e.getMessage());
650
}
651
}
652
653
public void processInParallel() {
654
List<Callable<String>> tasks = Arrays.asList(
655
() -> "Task 1 result",
656
() -> "Task 2 result",
657
() -> "Task 3 result"
658
);
659
660
try {
661
List<String> results = Tasks.executeParallel(tasks, executor);
662
System.out.println("Parallel results: " + results);
663
664
} catch (Exception e) {
665
System.err.println("Parallel execution failed: " + e.getMessage());
666
}
667
}
668
669
public void schedulePeriodicTask() {
670
ScheduledFuture<?> future = Tasks.executePeriodically(
671
() -> System.out.println("Periodic task executed at: " + new Date()),
672
0, 30, TimeUnit.SECONDS, scheduler
673
);
674
675
// Cancel after 5 minutes
676
scheduler.schedule(() -> future.cancel(false), 5, TimeUnit.MINUTES);
677
}
678
}
679
```