use of eu.esdihumboldt.hale.common.align.transformation.report.impl.CellLog in project hale by halestudio.
the class ConceptualSchemaTransformer method doTypeTransformation.
/**
* Execute a type transformation based on single type cell
*
* @param transformation the transformation to use
* @param typeCell the type cell
* @param target the target instance sink
* @param source the source instances
* @param alignment the alignment
* @param engines the engine manager
* @param transformer the property transformer
* @param context the transformation execution context
* @param reporter the reporter
* @param progressIndicator the progress indicator
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void doTypeTransformation(TypeTransformationFactory transformation, Cell typeCell, InstanceCollection source, InstanceSink target, Alignment alignment, EngineManager engines, PropertyTransformer transformer, TransformationContext context, TransformationReporter reporter, ProgressIndicator progressIndicator) {
TransformationLog cellLog = new CellLog(reporter, typeCell);
TypeTransformation<?> function;
try {
function = transformation.createExtensionObject();
} catch (Exception e) {
reporter.error(new TransformationMessageImpl(typeCell, "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 type transformation: No matching transformation engine found", null));
return;
}
// prepare transformation configuration
ListMultimap<String, Type> targetTypes = ArrayListMultimap.create();
for (Entry<String, ? extends Entity> entry : typeCell.getTarget().entries()) {
targetTypes.put(entry.getKey(), (Type) entry.getValue());
}
ListMultimap<String, ParameterValue> parameters = typeCell.getTransformationParameters();
if (parameters != null) {
parameters = Multimaps.unmodifiableListMultimap(parameters);
}
Map<String, String> executionParameters = transformation.getExecutionParameters();
// break on cancel
if (progressIndicator.isCanceled()) {
return;
}
ResourceIterator<FamilyInstance> iterator;
if (typeCell.getSource() == null || typeCell.getSource().isEmpty()) {
// type cell w/o source
// -> execute exactly once w/ null source
source = null;
iterator = new GenericResourceIteratorAdapter<Object, FamilyInstance>(Collections.singleton(null).iterator()) {
@Override
protected FamilyInstance convert(Object next) {
return null;
}
};
} else {
// Step 1: selection
// Select only instances that are relevant for the transformation.
source = source.select(new TypeCellFilter(typeCell));
// Step 2: partition
// use InstanceHandler if available - for example merge or join
function.setExecutionContext(context.getCellContext(typeCell));
InstanceHandler instanceHandler = function.getInstanceHandler();
if (instanceHandler != null) {
injectTransformationContext(instanceHandler, context);
progressIndicator.setCurrentTask("Perform instance partitioning");
try {
iterator = instanceHandler.partitionInstances(source, transformation.getFunctionId(), engine, parameters, executionParameters, cellLog);
} catch (TransformationException e) {
cellLog.error(cellLog.createMessage("Type transformation: partitioning failed", e));
return;
}
} else {
// else just use every instance as is
iterator = new GenericResourceIteratorAdapter<Instance, FamilyInstance>(source.iterator()) {
@Override
protected FamilyInstance convert(Instance next) {
return new FamilyInstanceImpl(next);
}
};
}
}
progressIndicator.setCurrentTask("Execute type transformations");
try {
while (iterator.hasNext()) {
// break on cancel
if (progressIndicator.isCanceled()) {
return;
}
function.setSource(iterator.next());
function.setPropertyTransformer(transformer);
function.setParameters(parameters);
function.setTarget(targetTypes);
function.setExecutionContext(context.getCellContext(typeCell));
try {
((TypeTransformation) function).execute(transformation.getFunctionId(), engine, executionParameters, cellLog, typeCell);
} catch (TransformationException e) {
cellLog.error(cellLog.createMessage("Type transformation failed, skipping instance.", e));
}
}
} finally {
iterator.close();
}
}
use of eu.esdihumboldt.hale.common.align.transformation.report.impl.CellLog 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);
}
}
}
}
}
Aggregations