Skip to main content

Nodes Comparison

The lionweb-java project provides model comparison through the ModelComparator class (in io.lionweb.utils). It performs a deep structural comparison of two nodes, checking properties, containments, references, and annotations recursively.

Basic Comparison

import io.lionweb.utils.ModelComparator;

ModelComparator comparator = new ModelComparator();
ModelComparator.ComparisonResult result = comparator.compare(nodeA, nodeB);

if (!result.areEquivalent()) {
result.getDifferences().forEach(System.out::println);
}

getDifferences() returns a list of human-readable strings describing each discrepancy found.

Quick Equivalence Check

For a simple yes/no answer, use the static helper:

boolean same = ModelComparator.areEquivalent(nodeA, nodeB);

Use in Tests

The most common use case is verifying that a round-trip through serialization and deserialization produces an identical model:

import io.lionweb.serialization.JsonSerialization;
import io.lionweb.serialization.SerializationProvider;
import io.lionweb.utils.ModelComparator;

JsonSerialization serialization = SerializationProvider.getStandardJsonSerialization();
serialization.enableDynamicNodes();

// Serialize to JSON and deserialize back
String json = serialization.serializeTreesToJsonString(original);
Node deserialized = serialization.deserializeToNodes(json).get(0);

// Assert structural equivalence
ModelComparator.ComparisonResult result = new ModelComparator().compare(original, deserialized);
assertTrue("Round-trip produced differences: " + result.getDifferences(),
result.areEquivalent());

What Gets Compared

The comparator performs a deep comparison across:

AspectWhat is checked
PropertiesAll property values defined by the classifier
ContainmentsNumber of children and recursive comparison of each child
ReferencesNumber of references, referenced node IDs, resolve info
AnnotationsNumber of annotations and their structures
StructureParent-child relationships, concept/classifier assignments

All differences are reported with contextual information: the node IDs involved, the feature name, and (for lists) the index position.

Comparing Annotation Instances

ModelComparator provides overloaded compare() methods for different element types:

// Compare two Node objects
comparator.compare(nodeA, nodeB);

// Compare two AnnotationInstance objects
comparator.compare(annotationA, annotationB);

// Polymorphic — works for any ClassifierInstance
comparator.compare(instanceA, instanceB);

ComparisonResult

ComparisonResult is a nested class within ModelComparator:

  • areEquivalent() — returns true when no differences were found
  • getDifferences() — returns a List<String> describing each difference