use of eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition in project hale by halestudio.
the class AbstractPropertyTransformationHandler method handleAsFeatureGmlId.
/**
* This method is invoked when the target type is the feature type owning
* this attribute mapping, and the target property is <code>gml:id</code>,
* which needs special handling.
*
* <p>
* In practice, this means that <code><idExpression></code> is used in
* place of:
*
* <pre>
* <ClientProperty>
* <name>...</name>
* <value>...</value>
* </ClientProperty>
* </pre>
*
* and that the target attribute is set to the mapped feature type name.
*
* </p>
*
* @param featureType the target feature type
* @param mappingName the target feature type's mapping name (may be
* <code>null</code>)
* @param context the app-schema mapping context
*/
protected void handleAsFeatureGmlId(TypeDefinition featureType, String mappingName, AppSchemaMappingContext context) {
PropertyEntityDefinition targetPropertyEntityDef = targetProperty.getDefinition();
List<ChildContext> gmlIdPath = targetPropertyEntityDef.getPropertyPath();
attributeMapping = context.getOrCreateAttributeMapping(featureType, mappingName, gmlIdPath);
// set targetAttribute to feature type qualified name
attributeMapping.setTargetAttribute(featureTypeMapping.getTargetElement());
// set id expression
AttributeExpressionMappingType idExpression = new AttributeExpressionMappingType();
idExpression.setOCQL(getSourceExpressionAsCQL());
// TODO: not sure whether any CQL expression can be used here
attributeMapping.setIdExpression(idExpression);
}
use of eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition in project hale by halestudio.
the class FormattedStringHandler method getSourceExpressionAsCQL.
/**
* @see eu.esdihumboldt.hale.io.appschema.writer.internal.AbstractPropertyTransformationHandler#getSourceExpressionAsCQL()
*/
@Override
protected String getSourceExpressionAsCQL() {
ListMultimap<String, ParameterValue> parameters = propertyCell.getTransformationParameters();
String pattern = parameters.get(PARAMETER_PATTERN).get(0).as(String.class);
List<int[]> startEndList = new ArrayList<int[]>();
List<String> varList = new ArrayList<String>();
Matcher m = VARIABLE_PATTERN.matcher(pattern);
while (m.find()) {
int[] startEnd = new int[2];
// index of '{' character
startEnd[0] = m.start();
// index of '}' character
startEnd[1] = m.end();
startEndList.add(startEnd);
// the variable name, without curly braces
varList.add(m.group(1));
}
// list of string to be concatenated, either string constants or
// variable names
String[] partsToConcat = new String[varList.size() * 2 + 1];
int lastPos = 0;
for (int i = 0; i < varList.size(); i++) {
int[] startEnd = startEndList.get(i);
String var = varList.get(i);
String textBeforeVar = pattern.substring(lastPos, startEnd[0]);
if (textBeforeVar != null && textBeforeVar.length() == 0) {
textBeforeVar = null;
}
partsToConcat[i * 2] = (textBeforeVar != null) ? "'" + textBeforeVar + "'" : null;
partsToConcat[i * 2 + 1] = var;
lastPos = startEnd[1];
}
// add text after last variable
String textAfterLastVar = pattern.substring(lastPos, pattern.length());
if (textAfterLastVar != null && textAfterLastVar.length() == 0) {
textAfterLastVar = null;
}
partsToConcat[partsToConcat.length - 1] = (textAfterLastVar != null) ? "'" + textAfterLastVar + "'" : null;
String strConcatExpr = "";
int lastPartIdx = 0;
while (lastPartIdx < partsToConcat.length) {
if (lastPartIdx == 0) {
// initialize strConcatExpr
for (int notNullIdx = lastPartIdx; notNullIdx < partsToConcat.length; notNullIdx++) {
if (partsToConcat[notNullIdx] != null) {
strConcatExpr = partsToConcat[notNullIdx];
lastPartIdx = notNullIdx;
break;
}
}
}
String secondArgument = null;
for (int notNullIdx = lastPartIdx + 1; notNullIdx < partsToConcat.length; notNullIdx++) {
if (partsToConcat[notNullIdx] != null) {
secondArgument = partsToConcat[notNullIdx];
lastPartIdx = notNullIdx;
break;
}
}
if (secondArgument != null) {
strConcatExpr = "strConcat(" + strConcatExpr + ", " + secondArgument + ")";
} else {
// no second argument could be found: should stop here
break;
}
}
// expression should be evaluated only if all conditions are met
if (propertyCell.getSource() != null) {
List<? extends Entity> sourceEntities = propertyCell.getSource().get(FormattedStringFunction.ENTITY_VARIABLE);
if (sourceEntities != null) {
for (Entity source : sourceEntities) {
PropertyEntityDefinition propEntityDef = (PropertyEntityDefinition) source.getDefinition();
strConcatExpr = getConditionalExpression(propEntityDef, strConcatExpr);
}
}
}
return strConcatExpr;
}
use of eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition in project hale by halestudio.
the class MathematicalExpressionHandler method getSourceExpressionAsCQL.
/**
* @see eu.esdihumboldt.hale.io.appschema.writer.internal.AbstractPropertyTransformationHandler#getSourceExpressionAsCQL()
*/
@Override
protected String getSourceExpressionAsCQL() {
// TODO: verify math expressions work as-is in CQL
String mathExpression = propertyCell.getTransformationParameters().get(PARAMETER_EXPRESSION).get(0).getStringRepresentation();
// expression should be evaluated only if all conditions are met
if (propertyCell.getSource() != null) {
List<? extends Entity> sourceEntities = propertyCell.getSource().get(MathematicalExpression.ENTITY_VARIABLE);
if (sourceEntities != null) {
for (Entity source : sourceEntities) {
PropertyEntityDefinition propEntityDef = (PropertyEntityDefinition) source.getDefinition();
mathExpression = getConditionalExpression(propEntityDef, mathExpression);
}
}
}
return mathExpression;
}
use of eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition 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.impl.PropertyEntityDefinition 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);
}
}
}
Aggregations