private void generateDeepConstructorGraph() {
StringBuilder dot = new StringBuilder("digraph G {\n");
dot.append(" rankdir=LR; node [shape=plain, fontname=\"Arial\", fontsize=10];\n\n");
Set<String> processed = new HashSet<>();
ApplicationContext current = this.startContext;
while (current != null) {
ConfigurableListableBeanFactory factory = ((ConfigurableApplicationContext) current).getBeanFactory();
for (String name : factory.getBeanDefinitionNames()) {
if (processed.add(name)) {
BeanDefinition def = factory.getBeanDefinition(name);
String color = name.toLowerCase().contains("comet") ? "#FFF9C4" :
(name.toLowerCase().contains("cpls") ? "#C8E6C9" : "#E1F5FE");
dot.append(String.format(" \"%s\" [label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" BGCOLOR=\"%s\">\n", name, color));
dot.append(String.format(" <TR><TD COLSPAN=\"2\"><B>%s</B></TD></TR>\n", xmlEscape(name)));
// 1. Standard Properties (like 'ordering')
for (PropertyValue pv : def.getPropertyValues().getPropertyValues()) {
String cleanVal = extractValue(pv.getValue());
dot.append(" <TR><TD ALIGN=\"LEFT\">").append(xmlEscape(pv.getName())).append("</TD>");
dot.append("<TD ALIGN=\"LEFT\">").append(xmlEscape(cleanVal)).append("</TD></TR>\n");
}
// 2. Constructor Arguments (like the ArrayList contents)
ConstructorArgumentValues cav = def.getConstructorArgumentValues();
// Check both Indexed and Generic arguments
Map<Integer, ConstructorArgumentValues.ValueHolder> indexedValues = cav.getIndexedArgumentValues();
for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : indexedValues.entrySet()) {
String cleanVal = extractValue(entry.getValue().getValue());
dot.append(" <TR><TD ALIGN=\"LEFT\"><I>arg[" + entry.getKey() + "]</I></TD>");
dot.append("<TD ALIGN=\"LEFT\">").append(xmlEscape(cleanVal)).append("</TD></TR>\n");
}
// Also check generic arguments if indexed are empty
if (indexedValues.isEmpty() && !cav.getGenericArgumentValues().isEmpty()) {
for (ConstructorArgumentValues.ValueHolder vh : cav.getGenericArgumentValues()) {
String cleanVal = extractValue(vh.getValue());
dot.append(" <TR><TD ALIGN=\"LEFT\"><I>arg[gen]</I></TD>");
dot.append("<TD ALIGN=\"LEFT\">").append(xmlEscape(cleanVal)).append("</TD></TR>\n");
}
}
dot.append(" </TABLE>>];\n");
for (String dep : factory.getDependenciesForBean(name)) {
dot.append(String.format(" \"%s\" -> \"%s\";\n", name, dep));
}
}
}
current = current.getParent();
}
dot.append("}\n");
System.out.println("----- COPY START -----\n" + dot.toString() + "\n----- COPY END -----");
}
private String extractValue(Object value) {
if (value == null) return "null";
if (value instanceof BeanReference) {
return "@" + ((BeanReference) value).getBeanName();
}
if (value instanceof TypedStringValue) {
return ((TypedStringValue) value).getValue();
}
if (value instanceof List) {
List<String> cleaned = new ArrayList<>();
for (Object item : (List<?>) value) {
cleaned.add(extractValue(item));
}
return cleaned.toString();
}
if (value instanceof Map) {
StringBuilder mapStr = new StringBuilder("{");
for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
mapStr.append(extractValue(entry.getKey())).append("=").append(extractValue(entry.getValue())).append(", ");
}
if (mapStr.length() > 1) mapStr.setLength(mapStr.length() - 2);
return mapStr.append("}").toString();
}
return value.toString();
}
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)