use of eu.esdihumboldt.hale.common.instance.model.MutableInstance 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.hale.common.instance.model.MutableInstance 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.hale.common.instance.model.MutableInstance in project hale by halestudio.
the class TreePropertyTransformer method publish.
/**
* @see PropertyTransformer#publish(FamilyInstance, MutableInstance,
* TransformationLog, Cell)
*/
@Override
public void publish(final FamilyInstance source, final MutableInstance target, final TransformationLog typeLog, final Cell typeCell) {
instanceCounter.adjustOrPutValue(typeCell, 1, 1);
// increase output type counter
reporter.stats().at("createdPerType").at(target.getDefinition().getName().toString()).next();
Runnable job = new Runnable() {
@Override
public void run() {
try {
SimpleLogContext.withLog(typeLog, () -> {
// Add the meta data ID of the source as SourceID to the
// target
Collection<Instance> sources = InstanceUtil.getInstanceOutOfFamily(source);
Set<Object> ids = new HashSet<Object>();
for (Instance inst : sources) {
// Merge instances may have multiple IDs
List<Object> sourceIDs = inst.getMetaData(InstanceMetadata.METADATA_ID);
if (sourceIDs != null) {
ids.addAll(sourceIDs);
}
}
InstanceMetadata.setSourceID(target, ids.toArray());
// identify transformations to be executed on given
// instances
// create/get a transformation tree
TransformationTree tree = treePool.getTree(typeCell);
// State: base tree
HooksUtil.executeTreeHooks(treeHooks, TreeState.MINIMAL, tree, target);
// apply instance value to transformation tree
InstanceVisitor instanceVisitor = new InstanceVisitor(source, tree, typeLog);
tree.accept(instanceVisitor);
// State: basic source populated tree
// duplicate subtree as necessary
DuplicationVisitor duplicationVisitor = new DuplicationVisitor(tree, typeLog);
tree.accept(duplicationVisitor);
duplicationVisitor.doAugmentationTrackback();
// State: source populated tree (duplication complete)
HooksUtil.executeTreeHooks(treeHooks, TreeState.SOURCE_POPULATED, tree, target);
// apply functions
for (FunctionExecutor functionExecutor : executors) {
functionExecutor.setTypeCell(typeCell);
tree.accept(functionExecutor);
}
// State: full tree (target populated)
HooksUtil.executeTreeHooks(treeHooks, TreeState.FULL, tree, target);
// fill instance
builder.populate(target, tree, typeLog);
// generate the rest of the metadatas
metaworkerthread.get().generate(target);
// XXX ok to add to sink in any thread?!
// XXX addInstance and close were made synchronized in
// OrientInstanceSink
// XXX instead collect instances and write them in only
// one
// thread?
// after property transformations, publish target
// instance
sink.addInstance(target);
// and release the tree for further use
treePool.releaseTree(tree);
});
} catch (Throwable e) {
/*
* Catch any error, as exceptions in the executor service
* will only result in a message on the console.
*/
typeLog.error(typeLog.createMessage("Error performing property transformations", e));
}
}
};
if (executorService != null) {
executorService.execute(job);
} else {
job.run();
}
}
use of eu.esdihumboldt.hale.common.instance.model.MutableInstance in project hale by halestudio.
the class InstanceValidator method validateChildren.
/**
* Validates the given property values (their values - as instances - and/or
* group children).
*
* @param properties the array of existing properties, may be null
* @param childDef their definition
* @param reporter the reporter to report to
* @param type the top level type
* @param path the current property path
* @param onlyCheckExistingChildren whether to only validate existing
* children (in case of a choice) or not
* @param reference the instance reference
* @param context the instance validation context
* @param entity the entity definition related to the property values or
* <code>null</code>
*/
private void validateChildren(Object[] properties, ChildDefinition<?> childDef, InstanceValidationReporter reporter, QName type, List<QName> path, boolean onlyCheckExistingChildren, InstanceReference reference, InstanceValidationContext context, @Nullable EntityDefinition entity) {
if (properties != null && properties.length > 0) {
for (Object property : properties) {
if (property instanceof Instance) {
validateInstance((Instance) property, reporter, type, path, onlyCheckExistingChildren, reference, context, childDef, entity);
} else if (property instanceof Group) {
validateGroupChildren((Group) property, reporter, type, path, onlyCheckExistingChildren, reference, context, childDef, entity);
} else {
if (childDef.asGroup() != null)
reporter.warn(new DefaultInstanceValidationMessage(reference, type, new ArrayList<QName>(path), "Wrong group", "A property is no group"));
else if (childDef.asProperty() != null) {
if (!skipValidation(childDef.asProperty().getPropertyType(), property)) {
// don't skip property
// wrap value in dummy instance for type validation
MutableInstance instance = new DefaultInstance(childDef.asProperty().getPropertyType(), null);
instance.setValue(property);
validateInstance(instance, reporter, type, path, onlyCheckExistingChildren, reference, context, childDef, entity);
}
}
}
}
} else {
/*
* Special case: No property value, but a combination of minimum
* cardinality greater than zero and NillableFlag is set. Then there
* can be sub-properties that are required.
*
* Applicable for XML (simple) types with mandatory attributes.
*/
if (childDef.asProperty() != null && childDef.asProperty().getConstraint(Cardinality.class).getMinOccurs() > 0 && childDef.asProperty().getConstraint(NillableFlag.class).isEnabled() && childDef.asProperty().getPropertyType().getConstraint(HasValueFlag.class).isEnabled() && !childDef.asProperty().getPropertyType().getChildren().isEmpty()) {
// collect XML attribute children
List<ChildDefinition<?>> attributes = new ArrayList<ChildDefinition<?>>();
for (ChildDefinition<?> child : childDef.asProperty().getPropertyType().getChildren()) {
if (child.asProperty() != null && child.asProperty().getConstraint(XmlAttributeFlag.class).isEnabled()) {
attributes.add(child);
}
}
if (!attributes.isEmpty()) {
// create an empty dummy instance
Instance instance = new DefaultInstance(childDef.asProperty().getPropertyType(), null);
validateGroupChildren(instance, attributes, reporter, type, path, onlyCheckExistingChildren, reference, context, entity);
}
}
}
}
use of eu.esdihumboldt.hale.common.instance.model.MutableInstance in project hale by halestudio.
the class Create method execute.
@Override
public void execute(String transformationIdentifier, TransformationEngine engine, Map<String, String> executionParameters, TransformationLog log, Cell cell) throws TransformationException {
// get number of executions
int num;
String numberExpr = getOptionalParameter(PARAM_NUMBER, Value.of(1)).as(String.class);
if (numberExpr != null) {
// replace variables
numberExpr = getExecutionContext().getVariables().replaceVariables(numberExpr);
try {
num = Integer.parseInt(numberExpr);
} catch (NumberFormatException e) {
log.error(log.createMessage("Unable to parse expression for number of instances to create", e));
num = 1;
}
} else {
num = 1;
}
for (int i = 0; i < num; i++) {
// create <number> of instances of the target type
TypeDefinition targetType = getTarget().values().iterator().next().getDefinition().getDefinition();
MutableInstance target = createInstance(targetType, i, log, cell);
getPropertyTransformer().publish(null, target, log, cell);
}
}
Aggregations