Skip to content
Snippets Groups Projects
Commit 9d2eaf94 authored by René Schöne's avatar René Schöne
Browse files

working on better visualization

- stereotype of NTAs is also hidden, and colors border of nodes now
parent 49dda403
No related branches found
No related tags found
1 merge request!9working on better visualization
Pipeline #12829 failed
aspect GenerationBackend { aspect GenerationBackend {
class DumpAst { class DumpAst {
private enum Source { enum Source {
RELATION, INVISIBLE_PARENT, PARENT, ROOT ROOT, NORMAL, RELATION
} }
}
class TransformationOptions { class TransformationOptions {
// todo should be read-only, i.e., copy-on-write // todo should be read-only, i.e., copy-on-write
public boolean relation = false; public Source source;
public boolean invisible = false; public boolean invisible;
public boolean root = false; public boolean allowNullObjects;
public boolean allowNullObject = false; public boolean computed;
public boolean computed = false;
public static TransformationOptions with() { public TransformationOptions asRelation() {
return new TransformationOptions(); return fromSource(Source.RELATION, false);
} }
public TransformationOptions relationTrue() { public TransformationOptions asRoot() {
TransformationOptions copy = new TransformationOptions(this); return fromSource(Source.ROOT, false);
copy.relation = true;
return copy;
} }
public TransformationOptions invisibleTrue() {
TransformationOptions copy = new TransformationOptions(this); public TransformationOptions asNormal(boolean shouldBeInvisible) {
copy.invisible = true; return fromSource(Source.NORMAL, shouldBeInvisible);
return copy;
} }
public TransformationOptions rootTrue() {
TransformationOptions copy = new TransformationOptions(this); public TransformationOptions computed(boolean computed) {
copy.root = true; if (computed == this.computed) {
return copy; return this;
} }
public TransformationOptions allowNullObjectTrue() { return new TransformationOptions(this.source, this.invisible, this.allowNullObjects, computed);
TransformationOptions copy = new TransformationOptions(this);
copy.allowNullObject = true;
return copy;
} }
public TransformationOptions computedTrue() {
TransformationOptions copy = new TransformationOptions(this); public TransformationOptions allowNullObjectsOnce() {
copy.computed = true; return new TransformationOptions(this.source, this.invisible, !DumpAst.this.getBuildConfig().getExcludeNullNodes(), this.computed);
return copy; }
private TransformationOptions fromSource(Source source, boolean shouldBeInvisible) {
return new TransformationOptions(source, this.invisible || shouldBeInvisible, this.computed);
}
private TransformationOptions(Source source, boolean invisible, boolean computed) {
this(source, invisible, false, computed);
} }
protected TransformationOptions() {} private TransformationOptions(Source source, boolean invisible, boolean allowNullObjects, boolean computed) {
protected TransformationOptions(TransformationOptions prototype) { this.source = source;
this.relation = prototype.relation; this.invisible = invisible;
this.invisible = prototype.invisible; this.allowNullObjects = allowNullObjects;
this.root = prototype.root; this.computed = computed;
this.allowNullObject = prototype.allowNullObject;
this.computed = prototype.computed;
} }
} }
}
private TransformationOptions DumpAst.options() {
return new TransformationOptions(Source.NORMAL, false, false);
}
// --- transform --- (need to be a method, because it alters the AST while traversing the object structure) // --- transform --- (need to be a method, because it alters the AST while traversing the object structure)
protected DumpNode DumpAst.transform(TransformationTransferInformation tti, Object obj) protected DumpNode DumpAst.transform(TransformationTransferInformation tti, Object obj)
throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException { throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException {
DumpNode result = transform(tti, obj, Source.ROOT); DumpNode result = transform(tti, obj, options().asRoot());
setRootNode(result); setRootNode(result);
// post-process relationTargetsUnprocessed // post-process relationTargetsUnprocessed
boolean someAreUnprocessed = true; boolean someAreUnprocessed = true;
...@@ -64,21 +65,18 @@ aspect GenerationBackend { ...@@ -64,21 +65,18 @@ aspect GenerationBackend {
java.util.Map<DumpNode, Boolean> copy = new java.util.HashMap<>(tti.relationTargetsUnprocessed); java.util.Map<DumpNode, Boolean> copy = new java.util.HashMap<>(tti.relationTargetsUnprocessed);
for (java.util.Map.Entry<DumpNode, Boolean> entry : copy.entrySet()) { for (java.util.Map.Entry<DumpNode, Boolean> entry : copy.entrySet()) {
if (entry.getValue()) { if (entry.getValue()) {
transform(tti, entry.getKey().getObject(), Source.ROOT); transform(tti, entry.getKey().getObject(), options().asRoot());
someAreUnprocessed = true; someAreUnprocessed = true;
} }
} }
} }
return result; return result;
} }
protected DumpNode DumpAst.transform(TransformationTransferInformation tti, Object obj, Source source)
throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException {
return transform(tti, obj, source, false);
}
protected DumpNode DumpAst.transform( protected DumpNode DumpAst.transform(
TransformationTransferInformation tti, Object obj, Source source, boolean allowNullObj) TransformationTransferInformation tti, Object obj, TransformationOptions options)
throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException { throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException {
if (obj == null && !allowNullObj) { if (obj == null && !options.allowNullObjects) {
return null; return null;
} }
DumpNode node; DumpNode node;
...@@ -91,7 +89,7 @@ aspect GenerationBackend { ...@@ -91,7 +89,7 @@ aspect GenerationBackend {
objClassName = obj.getClass().getSimpleName(); objClassName = obj.getClass().getSimpleName();
} }
if (node != null) { if (node != null) {
if (source == Source.RELATION) { if (options.source == Source.RELATION) {
return node; return node;
} }
// either processing as parent, or later as root-node. so mark it as processed. // either processing as parent, or later as root-node. so mark it as processed.
...@@ -100,6 +98,7 @@ aspect GenerationBackend { ...@@ -100,6 +98,7 @@ aspect GenerationBackend {
node = new DumpNode(); node = new DumpNode();
node.setObject(obj); node.setObject(obj);
node.setName("node" + (tti.nodeCounter++)); node.setName("node" + (tti.nodeCounter++));
node.setComputed(options.computed);
tti.transformed.put(obj, node); tti.transformed.put(obj, node);
this.addDumpNode(node); this.addDumpNode(node);
} }
...@@ -108,11 +107,11 @@ aspect GenerationBackend { ...@@ -108,11 +107,11 @@ aspect GenerationBackend {
} }
applyStyle(node); applyStyle(node);
// do not process node further if coming from a relation // do not process node further if coming from a relation
if (source == Source.RELATION) { if (options.source == Source.RELATION) {
tti.relationTargetsUnprocessed.put(node, true); tti.relationTargetsUnprocessed.put(node, true);
return node; return node;
} }
if (source == Source.INVISIBLE_PARENT || !isTypeEnabled(objClassName)) { if (options.invisible || !isTypeEnabled(objClassName)) {
node.setInvisible(true); node.setInvisible(true);
} }
if (obj == null) { if (obj == null) {
...@@ -125,7 +124,7 @@ aspect GenerationBackend { ...@@ -125,7 +124,7 @@ aspect GenerationBackend {
// -- singleChild -- // -- singleChild --
Object target = containmentMethod.getMethod().invoke(obj); Object target = containmentMethod.getMethod().invoke(obj);
String childName = containmentMethod.getName(); String childName = containmentMethod.getName();
DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)), !getBuildConfig().getExcludeNullNodes()); DumpNode targetNode = transform(tti, target, options.asNormal(!isChildEnabled(objClassName, childName)).allowNullObjectsOnce());
if (targetNode != null) { if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode(); DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName); normalChild.setName(childName);
...@@ -142,7 +141,7 @@ aspect GenerationBackend { ...@@ -142,7 +141,7 @@ aspect GenerationBackend {
boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName); boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName);
listChild.setName(childName); listChild.setName(childName);
for (Object target : targetList) { for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble)); DumpNode targetNode = transform(tti, target, options.asNormal(shouldBeInvisisble));
if (target != null && targetNode != null) { if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode)); listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode));
} }
...@@ -159,24 +158,26 @@ aspect GenerationBackend { ...@@ -159,24 +158,26 @@ aspect GenerationBackend {
// -- singleChild -- // -- singleChild --
Object target = otherMethod.getMethod().invoke(obj); Object target = otherMethod.getMethod().invoke(obj);
String childName = otherMethod.getName(); String childName = otherMethod.getName();
DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)), !getBuildConfig().getExcludeNullNodes()); boolean computed = otherMethod.asSingleChildMethod().isNTASingleChildMethod();
DumpNode targetNode = transform(tti, target, options.asNormal(!isChildEnabled(objClassName, childName)).computed(computed).allowNullObjectsOnce());
if (targetNode != null) { if (targetNode != null) {
DumpNormalChildNode normalChild = new DumpNormalChildNode(); DumpNormalChildNode normalChild = new DumpNormalChildNode();
normalChild.setName(childName); normalChild.setName(childName);
normalChild.setDumpNode(targetNode); normalChild.setDumpNode(targetNode);
normalChild.setComputed(otherMethod.asSingleChildMethod().isNTASingleChildMethod()); normalChild.setComputed(computed);
node.addDumpChildNode(normalChild); node.addDumpChildNode(normalChild);
} }
} else if (otherMethod.isListChildMethod()) { } else if (otherMethod.isListChildMethod()) {
// -- listChild -- // -- listChild --
Iterable<?> targetList = (Iterable<?>) otherMethod.getMethod().invoke(obj); Iterable<?> targetList = (Iterable<?>) otherMethod.getMethod().invoke(obj);
DumpListChildNode listChild = new DumpListChildNode(); DumpListChildNode listChild = new DumpListChildNode();
listChild.setComputed(otherMethod.asListChildMethod().isNTAListChildMethod()); boolean computed = otherMethod.asListChildMethod().isNTAListChildMethod();
listChild.setComputed(computed);
String childName = otherMethod.getName(); String childName = otherMethod.getName();
boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName); boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName);
listChild.setName(childName); listChild.setName(childName);
for (Object target : targetList) { for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble)); DumpNode targetNode = transform(tti, target, options.asNormal(shouldBeInvisisble).computed(computed));
if (target != null && targetNode != null) { if (target != null && targetNode != null) {
listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode)); listChild.addInnerDumpNode(new InnerDumpNode().setDumpNode(targetNode));
} }
...@@ -187,7 +188,7 @@ aspect GenerationBackend { ...@@ -187,7 +188,7 @@ aspect GenerationBackend {
} else if (otherMethod.isSingleRelationMethod()) { } else if (otherMethod.isSingleRelationMethod()) {
// -- singleRelation -- // -- singleRelation --
Object target = otherMethod.getMethod().invoke(obj); Object target = otherMethod.getMethod().invoke(obj);
DumpNode targetNode = transform(tti, target, Source.RELATION); DumpNode targetNode = transform(tti, target, options.asRelation());
if (target != null && targetNode != null) { if (target != null && targetNode != null) {
DumpNormalRelation normalRelation = new DumpNormalRelation(); DumpNormalRelation normalRelation = new DumpNormalRelation();
normalRelation.setName(otherMethod.getName()); normalRelation.setName(otherMethod.getName());
...@@ -200,7 +201,7 @@ aspect GenerationBackend { ...@@ -200,7 +201,7 @@ aspect GenerationBackend {
DumpListRelation listRelation = new DumpListRelation(); DumpListRelation listRelation = new DumpListRelation();
listRelation.setName(otherMethod.getName()); listRelation.setName(otherMethod.getName());
for (Object target : targetList) { for (Object target : targetList) {
DumpNode targetNode = transform(tti, target, Source.RELATION); DumpNode targetNode = transform(tti, target, options.asRelation());
if (target != null && targetNode != null) { if (target != null && targetNode != null) {
listRelation.addInnerDumpNode(new InnerDumpNode(targetNode)); listRelation.addInnerDumpNode(new InnerDumpNode(targetNode));
} }
...@@ -212,7 +213,7 @@ aspect GenerationBackend { ...@@ -212,7 +213,7 @@ aspect GenerationBackend {
// -- token -- // -- token --
Object target = otherMethod.getMethod().invoke(obj); Object target = otherMethod.getMethod().invoke(obj);
if (target != null) { if (target != null) {
DumpNode targetNode = transform(tti, target, Source.RELATION); DumpNode targetNode = transform(tti, target, options.asRelation());
DumpToken token = null; DumpToken token = null;
// TODO check, if Iterable.isAssignableFrom(target.getClass()). // TODO check, if Iterable.isAssignableFrom(target.getClass()).
// if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's // if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's
...@@ -246,11 +247,6 @@ aspect GenerationBackend { ...@@ -246,11 +247,6 @@ aspect GenerationBackend {
node.setManualStereotypes(getBuildConfig().getStyleInformation().getStereotypeMethod().get(obj)); node.setManualStereotypes(getBuildConfig().getStyleInformation().getStereotypeMethod().get(obj));
} }
private Source DumpAst.nextSource(Source currentSource, boolean shouldBeInvisible) {
return currentSource == Source.INVISIBLE_PARENT ? Source.INVISIBLE_PARENT :
(shouldBeInvisible ? Source.INVISIBLE_PARENT : Source.PARENT);
}
syn nta ClassAnalysisResult DumpAst.analyzeClass(java.lang.Class<?> clazz) { syn nta ClassAnalysisResult DumpAst.analyzeClass(java.lang.Class<?> clazz) {
ClassAnalysisResult result = new ClassAnalysisResult(); ClassAnalysisResult result = new ClassAnalysisResult();
String clazzName = clazz.getSimpleName(); String clazzName = clazz.getSimpleName();
...@@ -565,7 +561,6 @@ aspect GenerationBackend { ...@@ -565,7 +561,6 @@ aspect GenerationBackend {
// --- isAstNode --- // --- isAstNode ---
syn boolean DumpNode.isAstNode() { syn boolean DumpNode.isAstNode() {
if (getObject() == null) { if (getObject() == null) {
// todo: check if false works
return false; return false;
} }
Class<?> clazz = getObject().getClass(); Class<?> clazz = getObject().getClass();
......
...@@ -5,6 +5,10 @@ skinparam object<<null>> { ...@@ -5,6 +5,10 @@ skinparam object<<null>> {
shadowing false shadowing false
} }
hide <<null>> stereotype hide <<null>> stereotype
skinparam object<<NTA>> {
BorderColor {{{computedColor}}}
}
hide <<NTA>> stereotype
{{#PrintConfig}} {{#PrintConfig}}
scale {{{scale}}} scale {{{scale}}}
......
...@@ -2,6 +2,8 @@ aspect GrammarGlobal { ...@@ -2,6 +2,8 @@ aspect GrammarGlobal {
syn A C.getCalculated() { syn A C.getCalculated() {
A result = new A(); A result = new A();
result.setName("Calculated-" + getName()); result.setName("Calculated-" + getName());
D innerD = new D();
result.setD(innerD);
return result; return result;
} }
......
...@@ -163,7 +163,7 @@ public class TestUtils { ...@@ -163,7 +163,7 @@ public class TestUtils {
dumpAst.toPlantUml(); dumpAst.toPlantUml();
List<DumpNode> result = new ArrayList<>(); List<DumpNode> result = new ArrayList<>();
for (DumpNode dumpNode : dumpAst.getDumpNodeList()) { for (DumpNode dumpNode : dumpAst.getDumpNodeList()) {
if (dumpNode.isAstNode() && !dumpNode.getInvisible()) { if ((dumpNode.isAstNode() || dumpNode.isNull()) && !dumpNode.getInvisible()) {
result.add(dumpNode); result.add(dumpNode);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment