Search in sources :

Example 1 with SourceNodeImpl

use of eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.SourceNodeImpl 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 SourceNodeImpl

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

the class TargetContext method duplicateSource.

// /**
// * Checks whether the given source node is part of the context for the duplication.
// *
// * @param source the source node to check
// * @param info the context information
// * @return true, if the given node is in the context for the duplication, false otherwise
// */
// private boolean isInContext(SourceNode source, DuplicationInformation info) {
// Collection<SourceNode> contextNodes = info.getOldSourceNodes(source.getEntityDefinition());
// for (SourceNode node : contextNodes)
// if (node == source)
// return true;
// return false;
// }
// OLD STUFF!
// /**
// * Track back target nodes and duplicate any augmentation cells.
// * @param originalTarget the original target node
// * @param duplicationContext the duplication context
// */
// private void augmentationTrackback(TargetNode originalTarget,
// DuplicationContext duplicationContext) {
// // track back child augmentations
// for (TargetNode child : originalTarget.getChildren(false)) { //XXX should annotated children be included?
// augmentationTrackback(child, duplicationContext);
// }
// 
// // track back augmentations
// for (CellNode originalAssignment : originalTarget.getAssignments()) {
// /*
// * Duplicated target does not contain an assignment representing
// * the same cell as originalAssignment.
// */
// if (originalAssignment.getSources().isEmpty()) {
// // the cell is an augmentation, thus we duplicate it
// duplicateCell(originalAssignment, null, duplicationContext);
// /*
// * it is automatically added to the target nodes (which are
// * retrieved from the duplication context or created as
// * necessary)
// */
// }
// }
// }
// 
// /**
// * Track the graph back to sources that are missing in a cell node compared
// * to the original cell node.
// * @param cellNode the cell node
// * @param originalCell the original cell node the node was duplicated from
// */
// private void cellTrackback(CellNodeImpl cellNode, CellNode originalCell) {
// for (SourceNode originalSource : originalCell.getSources()) {
// if (!cellNode.getSources().contains(originalSource)) {
// /*
// * Duplicated cell does not contain a source representing the
// * same entity as originalSource.
// */
// SourceNode newSource = null;
// 
// // now there are several possible cases
// // a) the original source has leftovers and we grab one
// Leftovers leftovers = originalSource.getLeftovers();
// if (leftovers != null) {
// newSource = leftovers.consumeValue(originalCell.getCell());
// 
// if (newSource != null) {
// // interconnect both
// newSource.addRelation(cellNode);
// cellNode.addSource(originalCell.getSourceNames(originalSource),
// newSource);
// //XXX hard connections are OK here, as a leftover source is a duplicate
// }
// else {
// //TODO add an undefined source node in this case?
// }
// }
// 
// // b) the original source has a parent (ot it has a parent etc.)
// //    that has leftovers
// if (newSource == null) {
// //TODO
// }
// 
// // c) we use the original source node
// if (newSource == null) {
// newSource = originalSource;
// 
// // interconnect both
// newSource.addAnnotatedRelation(cellNode); //FIXME should be an augmentated relation!!!!
// cellNode.addSource(originalCell.getSourceNames(originalSource),
// newSource);
// }
// }
// }
// }
/**
 * Duplicate a source node.
 *
 * @param source the source node to duplicate
 * @param parent the parent of the new source node
 * @param addToParent if the new source node should be added as child to the
 *            parent
 * @param duplicationContext the duplication context
 * @return the new duplicated source node or <code>null</code> if
 *         duplication was prohibited
 */
private SourceNode duplicateSource(SourceNode source, SourceNode parent, boolean addToParent, DuplicationContext duplicationContext) {
    // create duplicate
    SourceNode duplicate = new SourceNodeImpl(source.getEntityDefinition(), parent, addToParent);
    duplicate.setContext(source.getContext());
    return configureSourceDuplicate(source, duplicate, parent, duplicationContext, addToParent);
}
Also used : SourceNodeImpl(eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.SourceNodeImpl) SourceNode(eu.esdihumboldt.hale.common.align.model.transformation.tree.SourceNode)

Example 3 with SourceNodeImpl

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

the class InstanceVisitor method visit.

/**
 * @see AbstractSourceToTargetVisitor#visit(SourceNode)
 */
@Override
public boolean visit(SourceNode source) {
    if (source.getDefinition() instanceof TypeDefinition) {
        if (instance == null)
            return false;
        // source root
        if (source.getDefinition().equals(instance.getDefinition())) {
            // check type filter (if any)
            Filter filter = source.getEntityDefinition().getFilter();
            if (filter != null && !filter.match(instance)) {
                // instance does not match filter, don't descend further
                return false;
            /*
					 * XXX What about merged instances? Will this be OK for
					 * those? A type filter should only apply to the original
					 * instance if it is merged - but most filters should
					 * evaluate the same
					 */
            } else {
                // also sets the node to defined
                source.setValue(instance);
                for (FamilyInstance child : instance.getChildren()) {
                    // Find fitting SourceNodes.
                    Collection<SourceNode> candidateNodes = tree.getRootSourceNodes(child.getDefinition());
                    if (candidateNodes.isEmpty()) {
                        /*
							 * No node found - but this may be because no
							 * property of the type is mapped, but there still
							 * might be child instances (in a Join) that have
							 * types with associated relations. To prevent those
							 * being skipped we add an artificial node
							 * representing the instance.
							 */
                        candidateNodes = new ArrayList<>();
                        EntityDefinition entityDef = new TypeEntityDefinition(child.getDefinition(), SchemaSpaceID.SOURCE, null);
                        candidateNodes.add(new SourceNodeImpl(entityDef, null, false));
                    }
                    for (SourceNode candidateNode : candidateNodes) {
                        filter = candidateNode.getEntityDefinition().getFilter();
                        if (filter == null || filter.match(child)) {
                            // XXX add to all candidates!?
                            if (candidateNode.getValue() == null) {
                                candidateNode.setAnnotatedParent(source);
                                source.addAnnotatedChild(candidateNode);
                            } else {
                                // Duplicate here, because there is no
                                // guarantee, that the Duplication
                                // Visitor will visit candidateNode after
                                // this node.
                                SourceNodeImpl duplicateNode = new SourceNodeImpl(candidateNode.getEntityDefinition(), candidateNode.getParent(), false);
                                duplicateNode.setAnnotatedParent(source);
                                source.addAnnotatedChild(duplicateNode);
                                TransformationContext context = candidateNode.getContext();
                                duplicateNode.setContext(context);
                                if (context != null) {
                                    context.duplicateContext(candidateNode, duplicateNode, Collections.<Cell>emptySet(), log);
                                } else {
                                    /*
										 * Not sure what this really means if we
										 * get here.
										 * 
										 * Best guess: Probably that we weren't
										 * able to determine how the duplication
										 * of this source can be propagted to
										 * the target. Thus the duplicated node
										 * will probably not have any
										 * connection.
										 */
                                    log.warn(log.createMessage("No transformation context for duplicated node of source " + candidateNode.getDefinition().getDisplayName(), null));
                                }
                                candidateNode = duplicateNode;
                            }
                            // run instance visitor on that annotated child
                            InstanceVisitor visitor = new InstanceVisitor(child, tree, log);
                            candidateNode.accept(visitor);
                        }
                    }
                }
                return true;
            }
        } else
            return false;
    } else {
        Object parentValue = source.getParent().getValue();
        if (parentValue == null || !(parentValue instanceof Group)) {
            source.setDefined(false);
            return false;
        } else {
            Group parentGroup = (Group) parentValue;
            Definition<?> currentDef = source.getDefinition();
            Object[] values = parentGroup.getProperty(currentDef.getName());
            if (values == null) {
                source.setDefined(false);
                return false;
            }
            // check for contexts
            EntityDefinition entityDef = source.getEntityDefinition();
            // index context
            Integer index = AlignmentUtil.getContextIndex(entityDef);
            if (index != null) {
                // only use the value at the given index, if present
                if (index < values.length) {
                    // annotate with the value at the index
                    Object value = values[index];
                    source.setValue(value);
                    return true;
                } else {
                    source.setDefined(false);
                    return false;
                }
            }
            // condition context
            Condition condition = AlignmentUtil.getContextCondition(entityDef);
            if (condition != null) {
                if (condition.getFilter() == null) {
                    // assume exclusion
                    source.setDefined(false);
                    return false;
                }
                // apply condition as filter on values and continue with
                // those values
                Collection<Object> matchedValues = new ArrayList<Object>();
                for (Object value : values) {
                    // determine parent
                    Object parent = null;
                    SourceNode parentNode = source.getParent();
                    if (parentNode != null && parentNode.isDefined()) {
                        parent = parentNode.getValue();
                    }
                    // test the condition
                    if (AlignmentUtil.matchCondition(condition, value, parent)) {
                        matchedValues.add(value);
                    }
                }
                values = matchedValues.toArray();
            }
            // default behavior (default context)
            if (values.length >= 1) {
                // annotate with the first value
                Object value = values[0];
                source.setValue(value);
                source.setAllValues(values);
            } else {
                source.setDefined(false);
                return false;
            }
            if (values.length > 1) {
                // handle additional values
                Object[] leftovers = new Object[values.length - 1];
                System.arraycopy(values, 1, leftovers, 0, leftovers.length);
                source.setLeftovers(new LeftoversImpl(source, leftovers));
            }
            return true;
        }
    }
}
Also used : Condition(eu.esdihumboldt.hale.common.align.model.Condition) Group(eu.esdihumboldt.hale.common.instance.model.Group) ArrayList(java.util.ArrayList) TransformationContext(eu.esdihumboldt.hale.common.align.model.transformation.tree.context.TransformationContext) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) SourceNodeImpl(eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.SourceNodeImpl) TypeEntityDefinition(eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition) EntityDefinition(eu.esdihumboldt.hale.common.align.model.EntityDefinition) SourceNode(eu.esdihumboldt.hale.common.align.model.transformation.tree.SourceNode) TypeEntityDefinition(eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition) Filter(eu.esdihumboldt.hale.common.instance.model.Filter) LeftoversImpl(eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.LeftoversImpl) FamilyInstance(eu.esdihumboldt.hale.common.instance.model.FamilyInstance)

Aggregations

SourceNode (eu.esdihumboldt.hale.common.align.model.transformation.tree.SourceNode)3 SourceNodeImpl (eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.SourceNodeImpl)3 Condition (eu.esdihumboldt.hale.common.align.model.Condition)1 EntityDefinition (eu.esdihumboldt.hale.common.align.model.EntityDefinition)1 TypeEntityDefinition (eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition)1 CellNode (eu.esdihumboldt.hale.common.align.model.transformation.tree.CellNode)1 TransformationContext (eu.esdihumboldt.hale.common.align.model.transformation.tree.context.TransformationContext)1 CellNodeImpl (eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.CellNodeImpl)1 LeftoversImpl (eu.esdihumboldt.hale.common.align.model.transformation.tree.impl.LeftoversImpl)1 FamilyInstance (eu.esdihumboldt.hale.common.instance.model.FamilyInstance)1 Filter (eu.esdihumboldt.hale.common.instance.model.Filter)1 Group (eu.esdihumboldt.hale.common.instance.model.Group)1 TypeDefinition (eu.esdihumboldt.hale.common.schema.model.TypeDefinition)1 ArrayList (java.util.ArrayList)1