use of eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.TargetNodeImpl in project hale by halestudio.
the class TargetContext method duplicateTree.
/**
* Duplicates the transformation tree for the given target node to the given
* duplicate target node.
*
* @param target the original target node
* @param info the duplication info object
* @param log the transformation log
* @return a collection of newly created target nodes
*/
private static TargetNodeImpl duplicateTree(TargetNode target, DuplicationInformation info, TransformationLog log) {
GroupNode parent = null;
// Check if the parent node exists in the given context already.
if (target.getParent() instanceof TargetNode) {
Iterator<TargetNode> possibleParents = info.getAllTargetNodes(((TargetNode) target.getParent()).getEntityDefinition()).iterator();
while (possibleParents.hasNext()) {
TargetNode possibleParent = possibleParents.next();
if (info.getContextTargets().contains(target) || !possibleParent.getChildren(false).contains(target)) {
parent = possibleParent;
break;
}
}
} else if (target.getParent() instanceof TransformationTree && info.getContextTargets().contains(target)) {
// Reached root, but this is a possible target.
parent = target.getParent();
} else {
// Reached root, but this is no possible target or the parent is
// null!
// XXX instead log and return null or not connected TargetNode? See
// T O D O below
log.warn(log.createMessage("DuplicationContext present, but no matching target found.", null));
return null;
// throw new IllegalStateException(
// "DuplicationContext present, but no matching target found.");
}
if (parent == null) {
// Does not exist: recursion.
TargetNodeImpl duplicatedTarget = duplicateTree((TargetNode) target.getParent(), info, log);
if (duplicatedTarget == null) {
return null;
}
TargetNodeImpl newTarget = new TargetNodeImpl(target.getEntityDefinition(), duplicatedTarget);
info.addNewTargetNode(newTarget.getEntityDefinition(), newTarget);
duplicatedTarget.addChild(newTarget);
return newTarget;
} else {
// Exists: add as child.
TargetNodeImpl newTarget = new TargetNodeImpl(target.getEntityDefinition(), parent);
info.addNewTargetNode(newTarget.getEntityDefinition(), newTarget);
// as annotated child.
if (parent instanceof TargetNodeImpl && !parent.getChildren(false).contains(newTarget))
((TargetNodeImpl) parent).addChild(newTarget);
else
parent.addAnnotatedChild(newTarget);
return newTarget;
}
}
use of eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.TargetNodeImpl in project hale by halestudio.
the class TargetContext method duplicateTarget.
/**
* Duplicate a target node.
*
* @param target the original target node
* @param relation the relation to associated to the target node
* @param duplicationContext the duplication context
* @return the duplicated target node or <code>null</code> if duplication
* was prohibited
*/
private TargetNode duplicateTarget(TargetNode target, CellNode relation, DuplicationContext duplicationContext) {
TargetNodeImpl duplicatedTarget = duplicationContext.getNode(target.getEntityDefinition());
if (duplicatedTarget == null) {
// target node not created yet
boolean duplicateParent = true;
if (contextTargets.contains(target)) {
// this is an endpoint, as such this is the last node to be
// duplicated
duplicateParent = false;
}
GroupNode duplicatedParent;
if (duplicateParent) {
GroupNode parent = target.getParent();
if (parent instanceof TargetNode) {
// create a duplicated parent
duplicatedParent = duplicateTarget((TargetNode) parent, null, duplicationContext);
if (duplicatedParent == null) {
return null;
}
} else {
// thus this is not a valid path for duplication
return null;
}
} else {
duplicatedParent = target.getParent();
}
// create duplicate
duplicatedTarget = new TargetNodeImpl(target.getEntityDefinition(), duplicatedParent);
// add as annotated child to parent
duplicatedParent.addAnnotatedChild(duplicatedTarget);
// add to duplication context
duplicationContext.addNode(duplicatedTarget, target);
}
if (relation != null) {
// assign relation
duplicatedTarget.addAssignment(target.getAssignmentNames(relation), relation);
}
return duplicatedTarget;
}
use of eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.TargetNodeImpl in project hale by halestudio.
the class TargetContext method duplicateTree.
/**
* Duplicates the transformation tree for the given cell node to the given
* duplicate cell node.
*
* @param cell the original cell node
* @param duplicateCell the duplication target
* @param info the duplication info object
* @param log the transformation log
*/
private static void duplicateTree(CellNode cell, CellNode duplicateCell, DuplicationInformation info, TransformationLog log) {
// Duplicate targets.
for (TargetNode target : cell.getTargets()) {
TargetNodeImpl duplicatedTarget = duplicateTree(target, info, log);
if (duplicatedTarget != null) {
duplicateCell.addTarget(duplicatedTarget);
duplicatedTarget.addAssignment(target.getAssignmentNames(cell), duplicateCell);
}
}
}
use of eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.TargetNodeImpl 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