use of eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode 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;
}
use of eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode in project hale by halestudio.
the class TransformationTreeLabelProvider method getText.
/**
* @see GraphLabelProvider#getText(Object)
*/
@Override
public String getText(Object element) {
if (element instanceof IdentityWrapper<?>) {
element = ((IdentityWrapper<?>) element).getValue();
}
if (element instanceof EntityConnectionData) {
// text for connections
EntityConnectionData connection = (EntityConnectionData) element;
Set<String> names = null;
Object source = connection.source;
if (source instanceof IdentityWrapper<?>) {
source = ((IdentityWrapper<?>) source).getValue();
}
Object dest = connection.dest;
if (dest instanceof IdentityWrapper<?>) {
dest = ((IdentityWrapper<?>) dest).getValue();
}
if (source instanceof TargetNode && dest instanceof CellNode) {
names = ((TargetNode) source).getAssignmentNames((CellNode) dest);
}
if (source instanceof CellNode && dest instanceof SourceNode) {
names = ((CellNode) source).getSourceNames((SourceNode) dest);
}
if (names != null && !names.isEmpty()) {
if (names.contains(null)) {
names = new HashSet<String>(names);
names.remove(null);
if (!names.isEmpty()) {
names.add("(unnamed)");
}
}
// build name string
Joiner joiner = Joiner.on(',');
return joiner.join(names);
}
return "";
}
if (hasTransformationAnnotations(element)) {
if (element instanceof SourceNode) {
SourceNode node = (SourceNode) element;
if (node.isDefined()) {
Object value = node.getValue();
if (value == null) {
// no value
return "(not set)";
} else if (value instanceof Instance) {
// use the instance value if present
value = ((Instance) value).getValue();
}
if (value != null && !(value instanceof Group)) {
// TODO shorten if needed?
return value.toString();
}
// otherwise, just display the definition name
}
}
}
element = TransformationTreeUtil.extractObject(element);
return super.getText(element);
}
use of eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode in project hale by halestudio.
the class TreeGraphMLProvider method setVertexProperty.
/**
* sets the property of a [@link]Vertex from a [@link]TransformationNode
*
* @param node the node-object to get the name from
* @param vertex the vertex to set the property
*/
private void setVertexProperty(TransformationNode node, Vertex vertex) {
if (node instanceof TransformationTree) {
vertex.setProperty("name", ((TransformationTree) node).getType().getDisplayName());
vertex.setProperty("type", "root");
}
if (node instanceof TargetNode) {
vertex.setProperty("name", ((TargetNode) node).getDefinition().getDisplayName());
vertex.setProperty("type", "target");
}
if (node instanceof SourceNode) {
SourceNode snode = (SourceNode) node;
Object value = snode.getValue();
String name = ((SourceNode) node).getDefinition().getDisplayName();
if (value instanceof Group) {
vertex.setProperty("name", name);
vertex.setProperty("group", getChildrencountString(value));
vertex.setProperty("type", "source");
}
if (value instanceof Instance) {
if (((Instance) value).getValue() != null) {
vertex.setProperty("group", getChildrencountString(value));
vertex.setProperty("value", ((Instance) value).getValue().toString());
vertex.setProperty("type", "source");
}
} else {
vertex.setProperty("name", name);
vertex.setProperty("type", "source");
if (value instanceof String) {
vertex.setProperty("value", value);
}
}
}
if (node instanceof CellNode) {
vertex.setProperty("name", FunctionUtil.getFunction(((CellNode) node).getCell().getTransformationIdentifier(), null).getDisplayName());
vertex.setProperty("type", "cell");
}
}
use of eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode in project hale by halestudio.
the class FunctionExecutor method executeTransformation.
/**
* Execute a property transformation.
*
* @param transformation the transformation factory
* @param cell the alignment cell
* @param sources the named source entities and nodes
* @param targets the named target entities and nodes
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void executeTransformation(PropertyTransformationFactory transformation, Cell cell, ListMultimap<String, Pair<SourceNode, Entity>> sources, ListMultimap<String, Pair<TargetNode, Entity>> targets) {
TransformationLog cellLog = new CellLog(reporter, cell);
PropertyTransformation<?> function;
try {
// TODO cache function objects?
function = transformation.createExtensionObject();
} catch (Exception e) {
cellLog.error(cellLog.createMessage("Error creating transformation function.", e));
return;
}
TransformationEngine engine = engines.get(transformation.getEngineId(), cellLog);
if (engine == null) {
// TODO instead try another transformation
cellLog.error(cellLog.createMessage("Skipping property transformation: No matching transformation engine found", null));
return;
}
// configure function
// set expected result
ListMultimap<String, PropertyEntityDefinition> expectedResult = ArrayListMultimap.create(targets.keySet().size(), 1);
for (Entry<String, Pair<TargetNode, Entity>> targetEntry : targets.entries()) {
EntityDefinition def = targetEntry.getValue().getSecond().getDefinition();
expectedResult.put(targetEntry.getKey(), toPropertyEntityDefinition(def));
}
function.setExpectedResult(expectedResult);
// set source variables
ListMultimap<String, PropertyValue> variables = ArrayListMultimap.create();
for (Entry<String, Pair<SourceNode, Entity>> sourceEntry : sources.entries()) {
EntityDefinition def = sourceEntry.getValue().getSecond().getDefinition();
SourceNode sourceNode = sourceEntry.getValue().getFirst();
if (TransformationTreeUtil.isEager(cell, sourceNode, cellLog, context.getServiceProvider())) {
// eager source - all values
Object[] values = sourceNode.getAllValues();
if (values != null) {
for (int i = 0; i < values.length; i++) {
PropertyValue propertyValue = new PropertyValueImpl(values[i], toPropertyEntityDefinition(def));
variables.put(sourceEntry.getKey(), propertyValue);
}
}
} else {
// non-eager source - one value
Object value = sourceNode.getValue();
PropertyValue propertyValue = new PropertyValueImpl(value, toPropertyEntityDefinition(def));
variables.put(sourceEntry.getKey(), propertyValue);
}
}
function.setVariables(variables);
// set parameters
function.setParameters(cell.getTransformationParameters());
// set context
function.setExecutionContext(context.getCellContext(cell));
// set target type
TypeDefinition targetType = null;
if (!targets.isEmpty()) {
TargetNode target = targets.values().iterator().next().getFirst();
targetType = target.getEntityDefinition().getType();
}
function.setTargetType(targetType);
function.setTypeCell(typeCell.get());
// execute function
try {
((PropertyTransformation) function).execute(transformation.getIdentifier(), engine, transformation.getExecutionParameters(), cellLog, cell);
} catch (Throwable e) {
// TODO instead try another transformation?
cellLog.error(cellLog.createMessage("Skipping property transformation: Executing property transformation failed.", e));
return;
}
// apply function results
ListMultimap<String, Object> results = function.getResults();
if (results != null) {
for (String name : results.keySet()) {
List<Object> values = results.get(name);
List<Pair<TargetNode, Entity>> nodes = targets.get(name);
if (nodes.size() > values.size()) {
cellLog.warn(cellLog.createMessage(MessageFormat.format("Transformation result misses values for result with name {0}", name), null));
}
if (values.size() > nodes.size()) {
cellLog.warn(cellLog.createMessage(MessageFormat.format("More transformation results than target nodes for result with name {0}", name), null));
}
int count = Math.min(values.size(), nodes.size());
// node...
for (int i = 0; i < count; i++) {
Object value = values.get(i);
TargetNode node = nodes.get(i).getFirst();
if (value instanceof MultiValue) {
MultiValue originalValue = (MultiValue) value;
MultiValue processedValue = new MultiValue(originalValue.size());
for (Object o : originalValue) {
processedValue.add(processValue(cellLog, function, o, node));
}
value = processedValue;
} else {
value = processValue(cellLog, function, value, node);
}
/*
* TODO
*
* set node value only if no result has already been set. If
* a value is already there and we are in a lower priority
* executor, we do not overwrite.
*/
if (!node.isDefined()) {
node.setResult(value);
}
}
}
}
}
use of eu.esdihumboldt.hale.common.align.model.transformation.tree.TargetNode in project hale by halestudio.
the class InstanceBuilder method populateGroup.
/**
* Populates a group with values from its children.
*
* @param group the group
* @param node the node associated with the group
* @param typeLog the type transformation log
* @return if any values were added to the group
*/
private boolean populateGroup(MutableGroup group, GroupNode node, TransformationLog typeLog) {
boolean anyValue = false;
for (TargetNode child : node.getChildren(true)) {
Object value = getValue(child, typeLog);
if (value != NoObject.NONE) {
// add value to group
if (value instanceof MultiValue) {
MultiValue multiValue = (MultiValue) value;
int toAdd = multiValue.size();
// check cardinality
Cardinality card = DefinitionUtil.getCardinality(child.getDefinition());
if (card.getMaxOccurs() != Cardinality.UNBOUNDED && card.getMaxOccurs() < toAdd) {
toAdd = (int) card.getMaxOccurs();
typeLog.warn(typeLog.createMessage("Too many values present for " + child.getDefinition().getDisplayName() + ". Limiting to match cardinality.", null));
}
// add properties
for (int i = 0; i < toAdd; i++) {
group.addProperty(child.getDefinition().getName(), multiValue.get(i));
}
if (toAdd > 0) {
anyValue = true;
}
} else {
group.addProperty(child.getDefinition().getName(), value);
anyValue = true;
}
}
}
return anyValue;
}
Aggregations