test(java-oracle): measure the getter defaults XMLEncoder refers to
XMLEncoder shares equal Integer objects, so a node's x coordinate can be written as a reference to the result of JSidebarButton.getIconTextGap(). GetterDefaults constructs the classes like XMLDecoder does and records what the getters return (packages/fls/src/javaDefaults.json). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
// Measures the value a JavaBean getter returns on a freshly constructed object.
|
||||
// XMLEncoder shares equal Integer and Boolean objects: an int written once as
|
||||
// the result of a getter (`<void id="Integer0" property="iconTextGap"/>`) is
|
||||
// later referenced by id — e.g. as a node's x coordinate. Decoding such a file
|
||||
// needs these defaults; they are measured here, not guessed.
|
||||
//
|
||||
// Usage: java -cp filius.jar:lib/*:classes GetterDefaults <output json> <fqcn#property>...
|
||||
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class GetterDefaults {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Map<String, Object> result = new TreeMap<>();
|
||||
for (int index = 1; index < args.length; index++) {
|
||||
String key = args[index];
|
||||
String className = key.substring(0, key.indexOf('#'));
|
||||
String property = key.substring(key.indexOf('#') + 1);
|
||||
String simpleName = className.substring(className.lastIndexOf('.') + 1);
|
||||
try {
|
||||
Object value = className.equals("java.lang.ThreadGroup")
|
||||
// A Thread's uncaughtExceptionHandler is its group; XMLDecoder runs
|
||||
// in the main thread, so that is the group asked.
|
||||
? read(Thread.currentThread().getThreadGroup(), property)
|
||||
: read(Class.forName(className).getDeclaredConstructor().newInstance(), property);
|
||||
result.put(simpleName + "#" + property, value);
|
||||
} catch (Throwable error) {
|
||||
Throwable cause = error.getCause() != null ? error.getCause() : error;
|
||||
result.put(simpleName + "#" + property, Map.of("error", cause.toString()));
|
||||
}
|
||||
}
|
||||
try (FileOutputStream out = new FileOutputStream(args[0])) {
|
||||
out.write((FlsOracle.Json.write(result, "") + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
System.out.println("getter defaults: " + result.size());
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static Object read(Object target, String property) throws Exception {
|
||||
Method getter = null;
|
||||
for (PropertyDescriptor descriptor : Introspector.getBeanInfo(target.getClass()).getPropertyDescriptors()) {
|
||||
if (descriptor.getName().equals(property)) getter = descriptor.getReadMethod();
|
||||
}
|
||||
if (getter == null) getter = target.getClass().getMethod(property);
|
||||
Object value = getter.invoke(target);
|
||||
if (value == null || value instanceof Number || value instanceof Boolean || value instanceof String) return value;
|
||||
return Map.of("class", value.getClass().getName());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user