use of eu.esdihumboldt.hale.common.align.transformation.function.TransformationException in project hale by halestudio.
the class TargetCollector method toMultiValue.
/**
* Transforms the closures added to this collector to a {@link MultiValue}
* using the supplied builder.
*
* @param builder the instance builder for creating target instances
* @param type the type of the instance to create
* @param log the log
* @return a result value for all closures added to this collector
* @throws TransformationException if some of the collected targets do not
* match the specified type
*/
public MultiValue toMultiValue(InstanceBuilder builder, TypeDefinition type, SimpleLog log) throws TransformationException {
MultiValue result = new MultiValue(size());
// a) closures not allowed if the target is no instance
if (containsClosures && type.getChildren().isEmpty()) {
throw new TransformationException("An instance is not applicable for the target.");
}
// b) values not allowed if the target may not have a value
if (containsValues && !type.getConstraint(HasValueFlag.class).isEnabled() && !type.getConstraint(AugmentedValueFlag.class).isEnabled()) {
// this may be desired, e.g. when producing geometries for GML
if (containsGeometries) {
// only warning message for geometries
log.warn("Value provided for target that does not allow a value according to the schema, contains geometries");
} else {
// instead of a hard error, we just log an error
log.error("Value provided for target that does not allow a value according to the schema");
}
}
for (TargetData data : targetData) {
Object value;
if (data.instance != null) {
Instance instance = data.instance;
// value as instance value
if (data.value != null && instance instanceof MutableInstance) {
((MutableInstance) instance).setValue(data.value);
}
value = instance;
} else {
value = data.value;
}
result.add(value);
}
return result;
}
use of eu.esdihumboldt.hale.common.align.transformation.function.TransformationException in project hale by halestudio.
the class DateExtraction 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 {
if (getParameters() == null || getParameters().get(PARAMETER_DATE_FORMAT) == null || getParameters().get(PARAMETER_DATE_FORMAT).isEmpty()) {
throw new TransformationException(MessageFormat.format("Mandatory parameter {0} not defined", PARAMETER_DATE_FORMAT));
}
String dateFormat = getParameters().get(PARAMETER_DATE_FORMAT).get(0).as(String.class);
// replace transformation variables in date format
dateFormat = getExecutionContext().getVariables().replaceVariables(dateFormat);
String sourceString = variables.values().iterator().next().getValueAs(String.class);
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
try {
return sdf.parse(sourceString);
} catch (ParseException pe) {
throw new TransformationException("Error parsing the source string", pe);
}
}
use of eu.esdihumboldt.hale.common.align.transformation.function.TransformationException 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.function.TransformationException 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;
}
use of eu.esdihumboldt.hale.common.align.transformation.function.TransformationException in project hale by halestudio.
the class InlineTransformation method evaluate.
@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 {
List<PropertyValue> sources = variables.get(null);
if (sources.isEmpty()) {
throw new NoResultException("No source available to transform");
}
PropertyValue source = sources.get(0);
Object sourceValue = source.getValue();
if (sourceValue == null) {
throw new NoResultException("Source value is null");
}
if (!(sourceValue instanceof Instance)) {
throw new TransformationException("Sources for inline transformation must be instances");
}
Instance sourceInstance = (Instance) sourceValue;
TypeDefinition sourceType = sourceInstance.getDefinition();
// get the original alignment
Alignment orgAlignment = getExecutionContext().getAlignment();
MutableAlignment alignment = new DefaultAlignment(orgAlignment);
// identify relevant type cell(s)
MutableCell queryCell = new DefaultCell();
ListMultimap<String, Type> sourceEntities = ArrayListMultimap.create();
sourceEntities.put(null, new DefaultType(new TypeEntityDefinition(sourceType, SchemaSpaceID.SOURCE, null)));
queryCell.setSource(sourceEntities);
ListMultimap<String, Type> targetEntities = ArrayListMultimap.create();
targetEntities.put(null, new DefaultType(new TypeEntityDefinition(resultProperty.getDefinition().getPropertyType(), SchemaSpaceID.TARGET, null)));
queryCell.setTarget(targetEntities);
Collection<? extends Cell> candidates = alignment.getTypeCells(queryCell);
if (candidates.isEmpty()) {
log.error(log.createMessage("No type transformations found for inline transformation", null));
throw new NoResultException();
}
// filter alignment -> only keep relevant type relations
List<Cell> allTypeCells = new ArrayList<>(alignment.getTypeCells());
for (Cell cell : allTypeCells) {
// remove cell
alignment.removeCell(cell);
if (!cell.getTransformationMode().equals(TransformationMode.disabled)) {
// only readd if not disabled
MutableCell copy = new DefaultCell(cell);
if (candidates.contains(cell)) {
// readd as active
copy.setTransformationMode(TransformationMode.active);
} else {
// readd as passive
copy.setTransformationMode(TransformationMode.passive);
}
alignment.addCell(copy);
}
}
// prepare transformation input/output
DefaultInstanceCollection sourceInstances = new DefaultInstanceCollection();
sourceInstances.add(sourceInstance);
DefaultInstanceSink target = new DefaultInstanceSink();
// run transformation
TransformationService ts = getExecutionContext().getService(TransformationService.class);
if (ts == null) {
throw new TransformationException("Transformation service not available for inline transformation");
}
ProgressIndicator progressIndicator = new LogProgressIndicator();
TransformationReport report = ts.transform(alignment, sourceInstances, new ThreadSafeInstanceSink<InstanceSink>(target), getExecutionContext(), progressIndicator);
// copy report messages
log.importMessages(report);
if (!report.isSuccess()) {
// copy report messages
log.importMessages(report);
throw new TransformationException("Inline transformation failed");
}
// extract result
List<Instance> targetList = target.getInstances();
if (targetList.isEmpty()) {
log.error(log.createMessage("Inline transformation yielded no result", null));
throw new NoResultException("No result from inline transformation");
}
if (targetList.size() > 1) {
log.error(log.createMessage("Inline transformation yielded multiple results, only first result is used", null));
}
return targetList.get(0);
}
Aggregations