use of eu.esdihumboldt.hale.common.align.transformation.report.impl.TransformationMessageImpl in project hale by halestudio.
the class CellNodeValidator method validate.
/**
* Validate a cell node.
*
* @param node the cell node
* @param sources the named source entities and nodes
* @param targets the named target entities and nodes
* @return if the cell node is valid for execution
*/
protected boolean validate(CellNode node, ListMultimap<String, Pair<SourceNode, Entity>> sources, ListMultimap<String, Pair<TargetNode, Entity>> targets) {
String functionId = node.getCell().getTransformationIdentifier();
FunctionDefinition<?> function = serviceProvider.getService(FunctionService.class).getFunction(functionId);
if (function != null) {
// check source node occurrence for mandatory source entities
for (ParameterDefinition sourceParam : function.getSource()) {
int min = sourceParam.getMinOccurrence();
if (sources.get(sourceParam.getName()).size() < min) {
return false;
}
}
return true;
} else {
reporter.error(new TransformationMessageImpl(node.getCell(), "Invalid cell - function not found: " + functionId, null));
}
return false;
}
use of eu.esdihumboldt.hale.common.align.transformation.report.impl.TransformationMessageImpl in project hale by halestudio.
the class FunctionExecutor method processValid.
/**
* @see CellNodeValidator#processValid(Cell, ListMultimap, ListMultimap)
*/
@Override
protected void processValid(Cell cell, ListMultimap<String, Pair<SourceNode, Entity>> sources, ListMultimap<String, Pair<TargetNode, Entity>> targets) {
if (cell.getPriority() != functionPriority) {
// ignore the priorities that do not match
return;
}
/*
* if the result node is only one and its value had already been set, it
* is not necessary to execute this function of a lower priority. (if
* there are more than one target node we will need to execute them all
* and check at the end of the transformation.
*/
if (targets.size() == 1) {
TargetNode targetNode = targets.values().iterator().next().getFirst();
if (targetNode.isDefined()) {
// pass
return;
}
}
String functionId = cell.getTransformationIdentifier();
List<PropertyTransformationFactory> transformations = this.transformations.getPropertyTransformations(functionId);
if (transformations == null || transformations.isEmpty()) {
reporter.error(new TransformationMessageImpl(cell, MessageFormat.format("No transformation for function {0} found. Skipping property transformation.", functionId), null));
} else {
// TODO select based on e.g. preferred transformation engine?
PropertyTransformationFactory transformation = transformations.iterator().next();
executeTransformation(transformation, cell, sources, targets);
}
}
use of eu.esdihumboldt.hale.common.align.transformation.report.impl.TransformationMessageImpl in project hale by halestudio.
the class ConceptualSchemaTransformer method transform.
/**
* @see TransformationService#transform(Alignment, InstanceCollection,
* InstanceSink, ServiceProvider, ProgressIndicator)
*/
@Override
public TransformationReport transform(Alignment alignment, InstanceCollection source, InstanceSink target, ServiceProvider serviceProvider, ProgressIndicator progressIndicator) {
TransformationReporter reporter = new DefaultTransformationReporter("Instance transformation", true);
TransformationContext context = new TransformationContext(serviceProvider, alignment);
TransformationFunctionService functions = serviceProvider.getService(TransformationFunctionService.class);
final SubtaskProgressIndicator sub = new SubtaskProgressIndicator(progressIndicator) {
@Override
protected String getCombinedTaskName(String taskName, String subtaskName) {
return taskName + " (" + subtaskName + ")";
}
};
progressIndicator = sub;
target = new CountingInstanceSink(target) {
private long lastUpdate = 0;
@Override
protected void countChanged(int count) {
long now = System.currentTimeMillis();
if (now - lastUpdate > 100) {
// only update every 100
// milliseconds
lastUpdate = now;
sub.subTask(count + " transformed instances");
}
}
};
progressIndicator.begin("Transformation", ProgressIndicator.UNKNOWN);
try {
EngineManager engines = new EngineManager();
PropertyTransformer transformer = new TreePropertyTransformer(alignment, reporter, target, engines, context);
Collection<? extends Cell> typeCells = alignment.getActiveTypeCells();
// sort type cell by priority
typeCells = sortTypeCells(typeCells);
for (Cell typeCell : typeCells) {
if (progressIndicator.isCanceled()) {
break;
}
List<TypeTransformationFactory> transformations = functions.getTypeTransformations(typeCell.getTransformationIdentifier());
if (transformations == null || transformations.isEmpty()) {
reporter.error(new TransformationMessageImpl(typeCell, MessageFormat.format("No transformation for function {0} found. Skipped type transformation.", typeCell.getTransformationIdentifier()), null));
} else {
// TODO select based on e.g. preferred transformation
// engine?
TypeTransformationFactory transformation = transformations.iterator().next();
doTypeTransformation(transformation, typeCell, source, target, alignment, engines, transformer, context, reporter, progressIndicator);
}
}
progressIndicator.setCurrentTask("Wait for property transformer to complete");
// wait for the property transformer to complete
// cancel property transformations if process was canceled - this
// may leave transformed instances in inconsistent state
transformer.join(progressIndicator.isCanceled());
engines.dispose();
reporter.setSuccess(true);
return reporter;
} finally {
progressIndicator.end();
}
}
use of eu.esdihumboldt.hale.common.align.transformation.report.impl.TransformationMessageImpl in project hale by halestudio.
the class TransformationTreeUtil method isEager.
/**
* Determines if a cell is connected to a source node with eager source
* parameters.
*
* @param cell the cell node
* @param source the source node
* @param log the transformation log, may be <code>null</code>
* @param serviceProvider the service provider
* @return if the cell contained in the cell node has eager source
* parameters connected to the source node
*/
public static boolean isEager(CellNode cell, SourceNode source, TransformationLog log, ServiceProvider serviceProvider) {
// get all entity names the cell is associated to the source node with
Set<String> names = cell.getSourceNames(source);
PropertyFunctionDefinition function = FunctionUtil.getPropertyFunction(cell.getCell().getTransformationIdentifier(), serviceProvider);
if (function != null) {
Set<? extends PropertyParameterDefinition> defSources = function.getSource();
Set<String> eager = new HashSet<String>();
for (PropertyParameterDefinition sourceDef : defSources) {
String name = sourceDef.getName();
if (sourceDef.isEager() && names.contains(name)) {
eager.add(name);
}
}
if (!eager.isEmpty()) {
if (log != null && eager.size() != names.size()) {
log.warn(new TransformationMessageImpl(cell.getCell(), "Source node with a mix of eager and non-eager connections to a cell, treating as eager.", null));
}
return true;
}
}
return false;
}
use of eu.esdihumboldt.hale.common.align.transformation.report.impl.TransformationMessageImpl in project hale by halestudio.
the class AssignFromCollector method evaluate.
/**
* @see eu.esdihumboldt.hale.common.align.transformation.function.impl.AbstractSingleTargetPropertyTransformation#evaluate(java.lang.String,
* eu.esdihumboldt.hale.common.align.transformation.engine.TransformationEngine,
* com.google.common.collect.ListMultimap, java.lang.String,
* eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition,
* java.util.Map,
* eu.esdihumboldt.hale.common.align.transformation.report.TransformationLog)
*/
@Override
protected Object evaluate(String transformationIdentifier, TransformationEngine engine, ListMultimap<String, PropertyValue> variables, String resultName, PropertyEntityDefinition resultProperty, Map<String, String> executionParameters, TransformationLog log) throws TransformationException, NoResultException {
// XXX check anchor?
final Collector mainCollector = (Collector) getExecutionContext().getTransformationContext().get(ContextHelpers.KEY_COLLECTOR);
if (mainCollector == null) {
throw new TransformationException("Fatal: No collector has been created yet. Check function priority.");
}
final ParameterValue collectorName = getParameterChecked(PARAMETER_COLLECTOR);
if (collectorName == null || collectorName.isEmpty()) {
throw new TransformationException("Fatal: No collector name was specified.");
}
final Collector collector = mainCollector.getAt(collectorName.getValue().toString());
if (collector == null) {
throw new TransformationException(MessageFormat.format("Error retrieving collector \"{0}\"", collectorName.getValue().toString()));
} else if (collector.values().isEmpty()) {
log.warn(new TransformationMessageImpl(getCell(), MessageFormat.format("Collector \"{0}\" contains no values. If this is unexpected, check the spelling of the collector name and the priority of the transformation function.", collectorName.getStringRepresentation()), null));
}
// Determine where to assign the collected values
final TypeDefinition resultPropertyType = resultProperty.getDefinition().getPropertyType();
final PropertyDefinition targetProperty;
final ResultStrategy resultStrategy;
if (resultPropertyType.getConstraint(HasValueFlag.class).isEnabled()) {
// The result property can take values, therefore assign directly to
// property
targetProperty = resultProperty.getDefinition();
// No instance creation is required in this case
resultStrategy = ResultStrategy.USE_VALUE;
} else {
// Find child element/attribute that can be assigned the reference
targetProperty = Optional.ofNullable(findReferenceChildProperty(resultPropertyType)).orElseThrow(() -> new TransformationException("Fatal: No child property could be found to assign a reference to."));
resultStrategy = ResultStrategy.BUILD_INSTANCE;
}
List<Object> collectedReferences = helper.extractCollectedValues(collector);
// Process collected values if target property is a reference, otherwise
// use plain values
final Function<Object, Object> referenceStrategy;
if (targetProperty.getConstraint(Reference.class).isReference()) {
final Reference referenceConstraint = targetProperty.getConstraint(Reference.class);
// Use the idToReference method to construct the reference
referenceStrategy = referenceConstraint::idToReference;
} else {
referenceStrategy = Function.identity();
}
MultiValue result = new MultiValue();
collectedReferences.forEach(ref -> result.add(resultStrategy.createResult(resultPropertyType, targetProperty, referenceStrategy.apply(ref))));
return result;
}
Aggregations