Search in sources :

Example 1 with CellNodeImpl

use of eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.CellNodeImpl in project hale by halestudio.

the class TargetContext method duplicateTree.

/**
 * Duplicates the transformation tree for the given source node to the given
 * duplicate source node.
 *
 * @param source the original source node
 * @param duplicate the duplication target
 * @param info the duplication info object
 * @param log the transformation log
 * @param serviceProvider service provider for resolving functions
 */
private static void duplicateTree(SourceNode source, SourceNode duplicate, DuplicationInformation info, TransformationLog log, ServiceProvider serviceProvider) {
    // Duplicate relations.
    for (CellNode cell : source.getRelations(false)) {
        // check whether the cell is eager for the source node
        if (TransformationTreeUtil.isEager(cell, source, log, serviceProvider))
            continue;
        // Check whether the cell is ignored.
        if (info.isIgnoreCell(cell.getCell()))
            continue;
        // XXX prioritize already created cell nodes (in this run) over old
        // nodes?
        // First check whether an old cell node with a missing source
        // exists.
        // If so, add this source to the first so found cell.
        boolean usedOld = false;
        for (IdentityWrapper<CellNode> wrapper : info.getOldCellNodes(cell.getCell())) {
            CellNode oldCellNode = wrapper.getValue();
            // Skip the cell if it's full.
            if (oldCellNode.getSources().size() == cell.getSources().size())
                continue;
            // Check whether out duplicate source node is missing...
            if (!oldCellNode.getSources().contains(duplicate)) {
                usedOld = true;
                // Has to be a cell created with the cell constructor.
                ((CellNodeImpl) oldCellNode).addSource(cell.getSourceNames(source), duplicate);
                duplicate.addRelation(oldCellNode);
                break;
            }
        }
        // If no old cell was used, use a newly created one / create one.
        if (!usedOld) {
            CellNodeImpl duplicatedCell = info.getNewCellNode(cell.getCell());
            if (duplicatedCell == null) {
                // Create a new cell, augment it with existing sources, add
                // it to info and duplicate targets.
                duplicatedCell = new CellNodeImpl(cell.getCell());
                augmentCell(cell, duplicatedCell, info);
                info.addNewCellNode(cell.getCell(), duplicatedCell);
                duplicateTree(cell, duplicatedCell, info, log);
            }
            // Add as relation/source.
            duplicate.addRelation(duplicatedCell);
            duplicatedCell.addSource(cell.getSourceNames(source), duplicate);
        }
    }
    // Duplicate children.
    for (SourceNode child : source.getChildren(false)) {
        SourceNode duplicatedChild = new SourceNodeImpl(child.getEntityDefinition(), duplicate, true);
        duplicatedChild.setContext(child.getContext());
        duplicateTree(child, duplicatedChild, info, log, serviceProvider);
    }
}
Also used : SourceNodeImpl(eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.SourceNodeImpl) CellNode(eu.esdihumboldt.hale.common.align.model.transformation.tree.CellNode) SourceNode(eu.esdihumboldt.hale.common.align.model.transformation.tree.SourceNode) CellNodeImpl(eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.CellNodeImpl)

Example 2 with CellNodeImpl

use of eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.CellNodeImpl in project hale by halestudio.

the class TargetContext method duplicateCell.

/**
 * Get the duplicated cell node.
 *
 * @param relation the original cell node
 * @param duplicateSource the duplicated source node to be associated with
 *            the duplicated cell node, may be <code>null</code> if the cell
 *            is an augmentation
 * @param duplicationContext the context of the current duplication process
 * @return the duplicated cell node or <code>null</code> if duplication was
 *         prohibited
 */
private CellNode duplicateCell(CellNode relation, SourceNode duplicateSource, DuplicationContext duplicationContext) {
    if (duplicationContext.getIgnoreCells().contains(relation.getCell())) {
        // already handled)
        return null;
    }
    // try to retrieve cell node from context
    CellNodeImpl duplicate = duplicationContext.getNode(relation.getCell());
    if (duplicate == null) {
        // if not already done, create a duplicate of the cell
        duplicate = new CellNodeImpl(relation.getCell());
        // duplicate the target nodes as necessary
        List<TargetNode> targets = new ArrayList<TargetNode>(relation.getTargets().size());
        for (TargetNode target : relation.getTargets()) {
            TargetNode duplicatedTarget = duplicateTarget(target, duplicate, duplicationContext);
            if (duplicatedTarget != null) {
                targets.add(duplicatedTarget);
            }
        }
        if (targets.isEmpty()) {
            // exit if there are no targets nodes
            return null;
        // FIXME if a cell has different associated sources the cell
        // node will be repeatedly created and discarded
        }
        // add duplicated targets to duplicated cell
        for (TargetNode target : targets) {
            duplicate.addTarget(target);
        }
        // store duplicate in duplication context
        duplicationContext.addNode(duplicate, relation);
    }
    // add the duplicated source
    if (duplicateSource != null) {
        duplicate.addSource(relation.getSourceNames(duplicateSource), duplicateSource);
    }
    return duplicate;
}
Also used : TargetNode(eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode) ArrayList(java.util.ArrayList) CellNodeImpl(eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.CellNodeImpl)

Example 3 with CellNodeImpl

use of eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.CellNodeImpl 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;
        }
    });
}
Also used : EntityDefinition(eu.esdihumboldt.hale.common.align.model.EntityDefinition) CellNode(eu.esdihumboldt.hale.common.align.model.transformation.tree.CellNode) TargetNode(eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode) AbstractTargetToSourceVisitor(eu.esdihumboldt.hale.common.align.model.transformation.tree.visitor.AbstractTargetToSourceVisitor) HashMap(java.util.HashMap) CellNodeImpl(eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.CellNodeImpl) ArrayDeque(java.util.ArrayDeque) TargetNodeImpl(eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.TargetNodeImpl)

Aggregations

CellNodeImpl (eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.CellNodeImpl)3 CellNode (eu.esdihumboldt.hale.common.align.model.transformation.tree.CellNode)2 TargetNode (eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode)2 EntityDefinition (eu.esdihumboldt.hale.common.align.model.EntityDefinition)1 SourceNode (eu.esdihumboldt.hale.common.align.model.transformation.tree.SourceNode)1 SourceNodeImpl (eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.SourceNodeImpl)1 TargetNodeImpl (eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.TargetNodeImpl)1 AbstractTargetToSourceVisitor (eu.esdihumboldt.hale.common.align.model.transformation.tree.visitor.AbstractTargetToSourceVisitor)1 ArrayDeque (java.util.ArrayDeque)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1