use of eu.esdihumboldt.cst.MultiValue in project hale by halestudio.
the class AsMultiValueMetaClass method convertArrayToMultiValue.
/**
* Converts an object that is an array to a MultiValue.
*
* @param array the array object
* @return the MultiValue representing the array
*/
private static MultiValue convertArrayToMultiValue(Object array) {
Class<?> ofArray = array.getClass().getComponentType();
if (ofArray.isPrimitive()) {
MultiValue ar = new MultiValue();
int length = Array.getLength(array);
for (int i = 0; i < length; i++) {
ar.add(Array.get(array, i));
}
return ar;
} else {
return new MultiValue(Arrays.asList((Object[]) array));
}
}
use of eu.esdihumboldt.cst.MultiValue in project hale by halestudio.
the class FunctionExecutor method processValue.
/**
* Processes the given value. Does not handle {@link MultiValue}!
*
* @param cellLog the transformation log
* @param function the property function
* @param value the value to process
* @param node the target node
* @return the processed value
*/
private Object processValue(TransformationLog cellLog, PropertyTransformation<?> function, Object value, TargetNode node) {
if (function.allowAutomatedResultConversion()) {
if (!(value instanceof Group)) {
// convert value for target
try {
value = convert(value, toPropertyEntityDefinition(node.getEntityDefinition()));
} catch (Throwable e) {
// ignore, but create error
cellLog.error(cellLog.createMessage("Conversion according to target property failed, using value as is.", e));
}
} else {
// TODO any conversion necessary/possible
}
} else {
// unwrap value
if (value instanceof Value) {
value = ((Value) value).getValue();
}
}
/*
* If the value is no group, but it should be one, create an instance
* wrapping the value
*/
TypeDefinition propertyType = toPropertyEntityDefinition(node.getEntityDefinition()).getDefinition().getPropertyType();
if (!(value instanceof Group) && !propertyType.getChildren().isEmpty()) {
MutableInstance instance = new DefaultInstance(propertyType, null);
instance.setValue(value);
value = instance;
}
return value;
}
use of eu.esdihumboldt.cst.MultiValue in project hale by halestudio.
the class InstanceBuilder method getValue.
/**
* Get the value for a target node.
*
* @param node the target node
* @param typeLog the type transformation log
* @return the value or {@link NoObject#NONE} representing no value
*/
private Object getValue(TargetNode node, TransformationLog typeLog) {
if (node.getChildren(true).isEmpty()) {
// simple leaf
if (node.isDefined()) {
// XXX this is done in FunctionExecutor
return node.getResult();
} else {
return NoObject.NONE;
}
}
boolean isProperty = node.getDefinition().asProperty() != null;
boolean isGroup = node.getDefinition().asGroup() != null;
if (isProperty && node.isDefined()) {
// it's a property and we have a value/values
Object nodeValue = node.getResult();
if (!(nodeValue instanceof MultiValue)) {
// pack single value into multivalue
MultiValue nodeMultiValue = new MultiValue();
nodeMultiValue.add(nodeValue);
nodeValue = nodeMultiValue;
}
MultiValue nodeMultiValue = (MultiValue) nodeValue;
if (!nodeMultiValue.isEmpty()) {
// Create n instances
MultiValue resultMultiValue = new MultiValue(nodeMultiValue.size());
for (Object value : nodeMultiValue) {
// the value may have been wrapped in an Instance
if (value instanceof Instance) {
value = ((Instance) value).getValue();
}
MutableInstance instance = new DefaultInstance(node.getDefinition().asProperty().getPropertyType(), null);
instance.setValue(value);
// XXX since this is the same for all instances maybe do
// this on a dummy and only copy properties for each?
// XXX MultiValue w/ target node children => strange results
populateGroup(instance, node, typeLog);
resultMultiValue.add(instance);
}
return resultMultiValue;
}
// if nodeMultiValue is empty fall through to below
// it the instance could still have children even without a value
}
// it's a property or group with no value
MutableGroup group;
if (isGroup) {
group = new DefaultGroup(node.getDefinition().asGroup());
} else if (isProperty) {
group = new DefaultInstance(node.getDefinition().asProperty().getPropertyType(), null);
} else {
throw new IllegalStateException("Illegal child definition");
}
// populate with children
if (populateGroup(group, node, typeLog)) {
return group;
} else {
return NoObject.NONE;
}
}
use of eu.esdihumboldt.cst.MultiValue 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.cst.MultiValue 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;
}
Aggregations