use of eu.esdihumboldt.hale.common.align.model.transformation.tree.visitor.AbstractTargetToSourceVisitor in project hale by halestudio.
the class TargetContext method augmentationTrackback.
/**
* Track back target nodes and duplicate any augmentation cells.
*
* @param tree the tree to work on
*/
public static void augmentationTrackback(TransformationTree tree) {
final Map<EntityDefinition, TargetNode> targetNodesWithAugmentations = new HashMap<EntityDefinition, TargetNode>();
// Search for original target nodes
tree.accept(new AbstractTargetToSourceVisitor() {
Deque<Boolean> hasAugmentation = new ArrayDeque<Boolean>();
/**
* @see eu.esdihumboldt.hale.common.align.model.transformation.tree.visitor.AbstractTransformationNodeVisitor#visit(eu.esdihumboldt.hale.common.align.model.transformation.tree.CellNode)
*/
@Override
public boolean visit(CellNode cell) {
// hasAugmentation to true.
if (cell.getSources().isEmpty()) {
if (!hasAugmentation.getLast()) {
hasAugmentation.pop();
hasAugmentation.push(true);
}
}
return false;
}
/**
* @see eu.esdihumboldt.hale.common.align.model.transformation.tree.visitor.AbstractTransformationNodeVisitor#visit(eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode)
*/
@Override
public boolean visit(TargetNode target) {
// Simply add a new level to hasAugmentation starting with
// false.
hasAugmentation.push(false);
return true;
}
/**
* @see eu.esdihumboldt.hale.common.align.model.transformation.tree.visitor.AbstractTransformationNodeVisitor#leave(eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode)
*/
@Override
public void leave(TargetNode target) {
// If this nodes level in hasAugmentation is true...
if (hasAugmentation.pop()) {
// ... add it to targetNodesWithAugmentations and set
// parents level to true, too.
targetNodesWithAugmentations.put(target.getEntityDefinition(), target);
if (!hasAugmentation.isEmpty() && !hasAugmentation.getLast()) {
hasAugmentation.pop();
hasAugmentation.push(true);
}
}
}
/**
* @see eu.esdihumboldt.hale.common.align.model.transformation.tree.TransformationNodeVisitor#includeAnnotatedNodes()
*/
@Override
public boolean includeAnnotatedNodes() {
// Only look for original target nodes.
return false;
}
});
// Add augmentations to all target nodes (no copied target node got them
// yet)
tree.accept(new AbstractTargetToSourceVisitor() {
/**
* @see eu.esdihumboldt.hale.common.align.model.transformation.tree.visitor.AbstractTransformationNodeVisitor#visit(eu.esdihumboldt.hale.common.align.model.transformation.tree.CellNode)
*/
@Override
public boolean visit(CellNode cell) {
return false;
}
/**
* @see eu.esdihumboldt.hale.common.align.model.transformation.tree.visitor.AbstractTransformationNodeVisitor#visit(eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode)
*/
@Override
public boolean visit(TargetNode target) {
// TODO more intelligent behavior of when NOT to create the
// augmentation.
// For example if the augmentation belongs to a complex
// structure that can
// occur 0..n times, it should not be created for the first time
// due to an
// augmentation.
TargetNode originalTarget = targetNodesWithAugmentations.get(target.getEntityDefinition());
// Only have to do something if the node is present in the map.
if (originalTarget != null && originalTarget != target) {
// sources are missing).
for (CellNode originalAssignment : originalTarget.getAssignments()) {
if (originalAssignment.getSources().isEmpty()) {
CellNodeImpl duplicatedAssignment = new CellNodeImpl(originalAssignment.getCell());
duplicatedAssignment.addTarget(target);
((TargetNodeImpl) target).addAssignment(originalTarget.getAssignmentNames(originalAssignment), duplicatedAssignment);
}
}
// Check for missing children.
for (TargetNode child : originalTarget.getChildren(false)) {
// Only add missing children that need an augmentation.
if (targetNodesWithAugmentations.containsKey(child.getEntityDefinition()) && !target.getChildren(false).contains(child)) {
TargetNodeImpl duplicatedChild = new TargetNodeImpl(child.getEntityDefinition(), target);
((TargetNodeImpl) target).addChild(duplicatedChild);
// The child will be handled by this visior later.
}
}
return true;
} else
return false;
}
@Override
public boolean includeAnnotatedNodes() {
return true;
}
});
}
Aggregations