use of eu.esdihumboldt.hale.common.align.model.EntityDefinition 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.EntityDefinition in project hale by halestudio.
the class EntityVisitor method accept.
/**
* Apply the visitor on a property entity definition.
*
* @param ped the property entity definition
*/
public void accept(PropertyEntityDefinition ped) {
if (visit(ped)) {
for (ChildDefinition<?> child : ped.getDefinition().getPropertyType().getChildren()) {
EntityDefinition ed = AlignmentUtil.getChild(ped, child.getName());
accept(ed);
}
}
}
use of eu.esdihumboldt.hale.common.align.model.EntityDefinition in project hale by halestudio.
the class EntityVisitor method accept.
/**
* Apply the visitor on a child entity definition.
*
* @param ced the child entity definition
*/
public void accept(ChildEntityDefinition ced) {
if (visit(ced)) {
for (ChildDefinition<?> child : ced.getDefinition().asGroup().getDeclaredChildren()) {
EntityDefinition ed = AlignmentUtil.getChild(ced, child.getName());
accept(ed);
}
}
}
use of eu.esdihumboldt.hale.common.align.model.EntityDefinition in project hale by halestudio.
the class GenerateDuplicates method generateMapping.
private void generateMapping() {
System.out.println("Indexing example cells...");
// index all cells based on the target property name
SetMultimap<String, Cell> exampleCells = HashMultimap.create();
for (Cell cell : examples.getCells()) {
if (cell.getTarget().size() == 1) {
// only supports cells with one target
EntityDefinition entityDef = CellUtil.getFirstEntity(cell.getTarget()).getDefinition();
if (entityDef.getDefinition() instanceof PropertyDefinition) {
if (ADE_NS.equals(entityDef.getDefinition().getName().getNamespaceURI())) {
exampleCells.put(entityDef.getDefinition().getName().getLocalPart(), cell);
} else
System.out.println("WARNING: ignoring cell with non-ADE target property");
} else
System.out.println("WARNING: ignoring type cell");
} else
System.out.println("WARNING: ignoring cell with multiple or no targets");
}
// collect all ADE feature types
List<TypeDefinition> featureTypes = BGISAppUtil.getADEFeatureTypes(targetSchema);
// visit ADE properties and create cells
System.out.println("Generating mapping from example cells for");
String cellNote = MessageFormat.format("Generated through duplication of example cells on BGIS ADE feature types.\n" + "{0,date,medium}", new Date());
DuplicateVisitor visitor = new DuplicateVisitor(exampleCells, cellNote);
for (TypeDefinition type : featureTypes) {
System.out.println(type.getDisplayName() + "...");
visitor.accept(new TypeEntityDefinition(type, SchemaSpaceID.TARGET, null));
}
if (visitor.getCells().isEmpty()) {
System.out.println("WARNING: no cells were created");
} else {
System.out.println(visitor.getCells().size() + " cells were created.");
}
// create alignment
MutableAlignment align = new DefaultAlignment();
for (MutableCell cell : visitor.getCells()) {
align.addCell(cell);
}
this.alignment = align;
}
use of eu.esdihumboldt.hale.common.align.model.EntityDefinition in project hale by halestudio.
the class CityGMLPropagateVisitor method findSourceTypes.
/**
* Find source types to use to propagate the given example cell. If
* possible, common super types will be returned.
*
* @param exampleCell the example cell
* @param targetType the target type
* @param index the index to store the replacement property paths in
* @return the source types to propagate the cell to
*/
private Collection<TypeDefinition> findSourceTypes(Cell exampleCell, TypeDefinition targetType, TypeEntityIndex<List<ChildContext>> index) {
Set<TypeDefinition> possibleSources = findAllPossibleSources(targetType);
/*
* Add all super types, because if possible, we want to do the mapping
* on super types.
*/
Set<TypeDefinition> superTypes = new HashSet<TypeDefinition>();
for (TypeDefinition type : possibleSources) {
TypeDefinition superType = type.getSuperType();
while (superType != null) {
if (superTypes.add(superType) || !possibleSources.contains(superType)) {
superType = superType.getSuperType();
} else {
superType = null;
}
}
}
possibleSources.addAll(superTypes);
/*
* Check source entities and filter all source types that don't match
* the entity.
*/
TypeDefinition originalSource = null;
for (Entity source : exampleCell.getSource().values()) {
EntityDefinition ed = source.getDefinition();
// check source type
if (originalSource == null) {
originalSource = ed.getType();
} else {
if (!originalSource.equals(ed.getType())) {
System.err.println("WARNING: ignoring cell with sources in different types");
return null;
}
}
if (ed.getPropertyPath().isEmpty()) {
// don't handle type cells
return null;
}
// remove all types w/o compatible property
Iterator<TypeDefinition> it = possibleSources.iterator();
while (it.hasNext()) {
TypeDefinition type = it.next();
List<ChildContext> newPath = hasCompatibleProperty(type, ed.getPropertyPath());
if (newPath == null) {
it.remove();
} else {
// remember child path per root type and entity
index.put(type, source, newPath);
}
}
}
/*
* Remove all types that have super types contained in the set.
*/
Set<TypeDefinition> toTest = new HashSet<TypeDefinition>(possibleSources);
for (TypeDefinition type : toTest) {
TypeDefinition superType = type.getSuperType();
while (superType != null) {
if (possibleSources.contains(superType)) {
possibleSources.remove(type);
// other super types are tested on their own
break;
}
superType = superType.getSuperType();
}
}
return possibleSources;
}
Aggregations