0
# Core Utilities
1
2
Essential utilities for key generation, transformations, predicates, string switching, parallel sorting, and low-level code generation support. These utilities provide foundational functionality used throughout CGLib and are also useful for application development.
3
4
## Capabilities
5
6
### KeyFactory
7
8
Generates classes for multi-valued keys with proper equals/hashCode implementations.
9
10
```java { .api }
11
/**
12
* Generates classes for multi-valued keys with proper equals/hashCode
13
*/
14
public abstract class KeyFactory {
15
/**
16
* Built-in customizer for class-by-name comparison
17
*/
18
public static final Customizer CLASS_BY_NAME;
19
20
/**
21
* Built-in customizer for object-by-class comparison
22
*/
23
public static final Customizer OBJECT_BY_CLASS;
24
25
/**
26
* Key factory for ASM types
27
*/
28
public static final KeyFactory HASH_ASM_TYPE;
29
30
/**
31
* Create key factory for interface
32
* @param keyInterface Interface defining key structure
33
* @return KeyFactory instance
34
*/
35
public static KeyFactory create(Class keyInterface);
36
37
/**
38
* Create key factory with customizer
39
* @param keyInterface Interface defining key structure
40
* @param customizer Customizer for key generation
41
* @return KeyFactory instance
42
*/
43
public static KeyFactory create(Class keyInterface, Customizer customizer);
44
45
/**
46
* Create key factory with multiple customizers
47
* @param keyInterface Interface defining key structure
48
* @param first First customizer
49
* @param next Additional customizers
50
* @return KeyFactory instance
51
*/
52
public static KeyFactory create(Class keyInterface, KeyFactoryCustomizer first, List<KeyFactoryCustomizer> next);
53
54
/**
55
* Create key factory with specific ClassLoader
56
* @param loader ClassLoader to use
57
* @param keyInterface Interface defining key structure
58
* @param customizer Customizer for key generation
59
* @return KeyFactory instance
60
*/
61
public static KeyFactory create(ClassLoader loader, Class keyInterface, Customizer customizer);
62
63
/**
64
* Create key instance
65
* @param args Values for key fields
66
* @return Key instance
67
*/
68
public abstract Object newInstance(Object[] args);
69
}
70
```
71
72
**Usage Examples:**
73
74
```java
75
// Define key interface
76
interface CacheKey {
77
// Key fields are inferred from interface methods
78
// equals/hashCode will be generated automatically
79
}
80
81
// Create key factory
82
KeyFactory keyFactory = KeyFactory.create(CacheKey.class);
83
84
// Create key instances
85
CacheKey key1 = (CacheKey) keyFactory.newInstance(new Object[]{"user", 123, "profile"});
86
CacheKey key2 = (CacheKey) keyFactory.newInstance(new Object[]{"user", 123, "profile"});
87
CacheKey key3 = (CacheKey) keyFactory.newInstance(new Object[]{"user", 456, "profile"});
88
89
// Keys with same values are equal
90
assert key1.equals(key2); // true
91
assert key1.hashCode() == key2.hashCode(); // true
92
assert !key1.equals(key3); // false
93
94
// Use in HashMap
95
Map<CacheKey, Object> cache = new HashMap<>();
96
cache.put(key1, "cached data");
97
Object data = cache.get(key2); // "cached data" - works because key1.equals(key2)
98
99
// Multi-field key interface
100
interface DatabaseKey {
101
String getTable();
102
Long getId();
103
String getOperation();
104
}
105
106
KeyFactory dbKeyFactory = KeyFactory.create(DatabaseKey.class);
107
DatabaseKey dbKey = (DatabaseKey) dbKeyFactory.newInstance(new Object[]{"users", 123L, "select"});
108
109
// Custom comparison with customizer
110
KeyFactory customFactory = KeyFactory.create(CacheKey.class, new Customizer() {
111
public void customize(CodeEmitter e, Type type) {
112
// Custom hash/equals logic if needed
113
}
114
});
115
```
116
117
### Converter Interface
118
119
Interface for converting values during operations like bean copying.
120
121
```java { .api }
122
/**
123
* Interface for converting values during operations
124
*/
125
public interface Converter {
126
/**
127
* Convert a value from one type to another
128
* @param value Source value
129
* @param target Target type
130
* @param context Context information (often property name)
131
* @return Converted value
132
*/
133
Object convert(Object value, Class target, Object context);
134
}
135
```
136
137
**Usage Examples:**
138
139
```java
140
// Date to String converter
141
Converter dateConverter = new Converter() {
142
public Object convert(Object value, Class target, Object context) {
143
if (value instanceof Date && target == String.class) {
144
return new SimpleDateFormat("yyyy-MM-dd").format((Date) value);
145
}
146
if (value instanceof String && target == Date.class) {
147
try {
148
return new SimpleDateFormat("yyyy-MM-dd").parse((String) value);
149
} catch (ParseException e) {
150
throw new RuntimeException(e);
151
}
152
}
153
return value;
154
}
155
};
156
157
// Use with BeanCopier
158
BeanCopier copier = BeanCopier.create(SourceBean.class, TargetBean.class, true);
159
SourceBean source = new SourceBean();
160
source.setCreatedDate(new Date());
161
162
TargetBean target = new TargetBean();
163
copier.copy(source, target, dateConverter);
164
// target.createdDate is now a String
165
166
// Type-safe converter
167
Converter numberConverter = new Converter() {
168
public Object convert(Object value, Class target, Object context) {
169
if (value == null) return null;
170
171
if (target == Integer.class || target == int.class) {
172
return Integer.valueOf(value.toString());
173
}
174
if (target == Double.class || target == double.class) {
175
return Double.valueOf(value.toString());
176
}
177
if (target == String.class) {
178
return value.toString();
179
}
180
return value;
181
}
182
};
183
```
184
185
### Transformer Interface
186
187
Interface for transforming objects.
188
189
```java { .api }
190
/**
191
* Interface for transforming objects
192
*/
193
public interface Transformer {
194
/**
195
* Transform a value
196
* @param value Input value
197
* @return Transformed value
198
*/
199
Object transform(Object value);
200
}
201
```
202
203
**Usage Examples:**
204
205
```java
206
// String transformer
207
Transformer upperCaseTransformer = new Transformer() {
208
public Object transform(Object value) {
209
return value != null ? value.toString().toUpperCase() : null;
210
}
211
};
212
213
// Number transformer
214
Transformer doubleTransformer = new Transformer() {
215
public Object transform(Object value) {
216
if (value instanceof Number) {
217
return ((Number) value).doubleValue() * 2;
218
}
219
return value;
220
}
221
};
222
223
// Chain transformers
224
Transformer chainedTransformer = new Transformer() {
225
public Object transform(Object value) {
226
value = upperCaseTransformer.transform(value);
227
value = doubleTransformer.transform(value);
228
return value;
229
}
230
};
231
232
// Use with collections
233
List<String> names = Arrays.asList("alice", "bob", "charlie");
234
List<String> upperNames = names.stream()
235
.map(name -> (String) upperCaseTransformer.transform(name))
236
.collect(Collectors.toList());
237
```
238
239
### Predicate Interface
240
241
Interface for boolean predicates used for filtering.
242
243
```java { .api }
244
/**
245
* Interface for boolean predicates
246
*/
247
public interface Predicate {
248
/**
249
* Evaluate predicate
250
* @param arg Input argument
251
* @return true if predicate matches
252
*/
253
boolean evaluate(Object arg);
254
}
255
```
256
257
**Usage Examples:**
258
259
```java
260
// String length predicate
261
Predicate longStringPredicate = new Predicate() {
262
public boolean evaluate(Object arg) {
263
return arg instanceof String && ((String) arg).length() > 5;
264
}
265
};
266
267
// Number range predicate
268
Predicate positiveNumberPredicate = new Predicate() {
269
public boolean evaluate(Object arg) {
270
return arg instanceof Number && ((Number) arg).doubleValue() > 0;
271
}
272
};
273
274
// Use for filtering
275
List<String> words = Arrays.asList("cat", "elephant", "dog", "hippopotamus");
276
List<String> longWords = new ArrayList<>();
277
for (String word : words) {
278
if (longStringPredicate.evaluate(word)) {
279
longWords.add(word);
280
}
281
}
282
// longWords contains ["elephant", "hippopotamus"]
283
284
// Combine predicates
285
Predicate combinedPredicate = new Predicate() {
286
public boolean evaluate(Object arg) {
287
return longStringPredicate.evaluate(arg) &&
288
arg.toString().startsWith("e");
289
}
290
};
291
```
292
293
294
### AbstractClassGenerator
295
296
Base class for code generation, providing common functionality for all CGLib generators.
297
298
```java { .api }
299
/**
300
* Base class for all code generators in CGLib
301
*/
302
public abstract class AbstractClassGenerator<T> {
303
/**
304
* Set class loader for generated classes
305
* @param classLoader ClassLoader to use
306
*/
307
public void setClassLoader(ClassLoader classLoader);
308
309
/**
310
* Set prefix for generated class names
311
* @param namePrefix Name prefix
312
*/
313
public void setNamePrefix(String namePrefix);
314
315
/**
316
* Set naming policy for generated classes
317
* @param namingPolicy Naming policy
318
*/
319
public void setNamingPolicy(NamingPolicy namingPolicy);
320
321
/**
322
* Enable or disable caching of generated classes
323
* @param useCache Whether to use cache
324
*/
325
public void setUseCache(boolean useCache);
326
327
/**
328
* Set whether to attempt loading existing classes
329
* @param attemptLoad Whether to attempt load
330
*/
331
public void setAttemptLoad(boolean attemptLoad);
332
333
/**
334
* Set generation strategy
335
* @param strategy Generation strategy
336
*/
337
public void setStrategy(GeneratorStrategy strategy);
338
339
/**
340
* Generate class bytecode (implement in subclasses)
341
* @param v ClassVisitor for bytecode generation
342
* @throws Exception If generation fails
343
*/
344
public abstract void generateClass(ClassVisitor v) throws Exception;
345
346
/**
347
* Create instance (used internally)
348
* @param key Generation key
349
* @return Generated instance
350
*/
351
protected T create(Object key);
352
353
/**
354
* Get default ClassLoader
355
* @return Default ClassLoader
356
*/
357
protected ClassLoader getDefaultClassLoader();
358
359
/**
360
* Get protection domain for generated classes
361
* @return ProtectionDomain
362
*/
363
protected ProtectionDomain getProtectionDomain();
364
365
/**
366
* Create first instance of generated class
367
* @param type Generated class
368
* @return First instance
369
* @throws Exception If creation fails
370
*/
371
protected Object firstInstance(Class type) throws Exception;
372
373
/**
374
* Create additional instances
375
* @param instance Existing instance
376
* @return New instance
377
* @throws Exception If creation fails
378
*/
379
protected Object nextInstance(Object instance) throws Exception;
380
}
381
```
382
383
### NamingPolicy Interface
384
385
Controls naming of generated classes.
386
387
```java { .api }
388
/**
389
* Policy for naming generated classes
390
*/
391
public interface NamingPolicy {
392
/**
393
* Generate class name
394
* @param prefix Name prefix
395
* @param source Source information
396
* @param key Generation key
397
* @param names Predicate for checking name conflicts
398
* @return Generated class name
399
*/
400
String getClassName(String prefix, String source, Object key, Predicate names);
401
}
402
```
403
404
### GeneratorStrategy Interface
405
406
Controls class generation strategy.
407
408
```java { .api }
409
/**
410
* Strategy for class generation
411
*/
412
public interface GeneratorStrategy {
413
/**
414
* Generate bytecode
415
* @param cg Class generator
416
* @return Generated bytecode
417
* @throws Exception If generation fails
418
*/
419
byte[] generate(ClassGenerator cg) throws Exception;
420
421
/**
422
* Check equality
423
* @param o Other object
424
* @return true if equal
425
*/
426
boolean equals(Object o);
427
}
428
```
429
430
### Customizer Interface
431
432
Customizes key generation in KeyFactory.
433
434
```java { .api }
435
/**
436
* Customizer for key generation
437
*/
438
public interface Customizer extends KeyFactoryCustomizer {
439
/**
440
* Customize code emission for key generation
441
* @param e Code emitter
442
* @param type Type being processed
443
*/
444
void customize(CodeEmitter e, Type type);
445
}
446
```