use of eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition in project hale by halestudio.
the class PropertyTypeCondition method accept.
/**
* @see EntityCondition#accept(Entity)
*/
@Override
public boolean accept(Property entity) {
TypeDefinition propertyType = entity.getDefinition().getDefinition().getPropertyType();
Type type = new DefaultType(new TypeEntityDefinition(propertyType, entity.getDefinition().getSchemaSpace(), null));
return typeCondition.accept(type);
}
use of eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition in project hale by halestudio.
the class InlineExplanation method getExplanation.
@Override
protected String getExplanation(Cell cell, boolean html, ServiceProvider services, Locale locale) {
Entity source = CellUtil.getFirstEntity(cell.getSource());
TypeEntityDefinition sourceType = getPropertyType(source);
Entity target = CellUtil.getFirstEntity(cell.getTarget());
TypeEntityDefinition targetType = getPropertyType(target);
if (sourceType != null && targetType != null) {
String retypeName = (html) ? ("<i>Retype</i>") : ("Retype");
String text = getMessage("main", locale);
return MessageFormat.format(text, formatEntity(source, html, true, locale), formatEntity(target, html, true, locale), formatEntity(sourceType, html, true, locale), formatEntity(targetType, html, true, locale), retypeName);
}
return null;
}
use of eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition in project hale by halestudio.
the class JoinParameter method validate.
/**
* Checks whether this join parameter is valid.<br>
* <br>
* Valid means, that there has to be at least two types, with each type
* after the first having at least one join condition on previous types.
*
* @param tryFix if it should be attempted to fix the configuration, the
* user is expected to complete it
*
* @return a error description or <code>null</code> if the parameter is
* valid.
*/
public String validate(boolean tryFix) {
// enough types?
if (types.size() < 2) {
return "Less than two types.";
}
// Check that each type is only in here once.
Set<TypeDefinition> typeSet = new HashSet<>();
for (TypeEntityDefinition type : types) {
if (typeSet.contains(type.getDefinition())) {
return "Same base type is used twice.";
} else {
typeSet.add(type.getDefinition());
}
}
// direct parent map
int[] parent = new int[types.size()];
// marker for found conditions for each type
boolean[] conditionFound = new boolean[types.size()];
// use sorted conditions (by join type)
List<JoinCondition> sortedConditions = new ArrayList<>(conditions);
Collections.sort(sortedConditions, new Comparator<JoinCondition>() {
@Override
public int compare(JoinCondition o1, JoinCondition o2) {
TypeEntityDefinition o1Type = AlignmentUtil.getTypeEntity(o1.baseProperty);
TypeEntityDefinition o2Type = AlignmentUtil.getTypeEntity(o2.baseProperty);
return types.indexOf(o1Type) - types.indexOf(o2Type);
}
});
// check types of each condition
for (JoinCondition condition : sortedConditions) {
TypeEntityDefinition baseType = AlignmentUtil.getTypeEntity(condition.baseProperty);
TypeEntityDefinition joinType = AlignmentUtil.getTypeEntity(condition.joinProperty);
int baseIndex = types.indexOf(baseType);
int joinIndex = types.indexOf(joinType);
// types have to exist, and join has to be after base
if (baseIndex == -1 || joinIndex == -1) {
if (tryFix) {
// remove wrong condition
this.conditions.remove(condition);
} else {
return "Property references no specified type.";
}
}
if (joinIndex <= baseIndex) {
if (tryFix) {
// remove wrong condition
this.conditions.remove(condition);
} else {
return "Invalid condition for type order.";
}
}
if (joinIndex >= 0) {
conditionFound[joinIndex] = true;
// sorted conditions allow this dependsOn-check
if (parent[joinIndex] < baseIndex) {
if (!dependsOn(baseIndex, parent[joinIndex], parent)) {
if (tryFix) {
// ignore
} else {
return "A join type depends on two types which do not depend on each other.";
}
}
parent[joinIndex] = baseIndex;
}
}
}
// check whether each type (except the first) has a join condition
for (int i = 1; i < conditionFound.length; i++) {
if (!conditionFound[i] && !tryFix) {
return "A joined type does not have any join conditions.";
}
}
return null;
}
use of eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition in project hale by halestudio.
the class InstanceVisitor method visit.
/**
* @see AbstractSourceToTargetVisitor#visit(SourceNode)
*/
@Override
public boolean visit(SourceNode source) {
if (source.getDefinition() instanceof TypeDefinition) {
if (instance == null)
return false;
// source root
if (source.getDefinition().equals(instance.getDefinition())) {
// check type filter (if any)
Filter filter = source.getEntityDefinition().getFilter();
if (filter != null && !filter.match(instance)) {
// instance does not match filter, don't descend further
return false;
/*
* XXX What about merged instances? Will this be OK for
* those? A type filter should only apply to the original
* instance if it is merged - but most filters should
* evaluate the same
*/
} else {
// also sets the node to defined
source.setValue(instance);
for (FamilyInstance child : instance.getChildren()) {
// Find fitting SourceNodes.
Collection<SourceNode> candidateNodes = tree.getRootSourceNodes(child.getDefinition());
if (candidateNodes.isEmpty()) {
/*
* No node found - but this may be because no
* property of the type is mapped, but there still
* might be child instances (in a Join) that have
* types with associated relations. To prevent those
* being skipped we add an artificial node
* representing the instance.
*/
candidateNodes = new ArrayList<>();
EntityDefinition entityDef = new TypeEntityDefinition(child.getDefinition(), SchemaSpaceID.SOURCE, null);
candidateNodes.add(new SourceNodeImpl(entityDef, null, false));
}
for (SourceNode candidateNode : candidateNodes) {
filter = candidateNode.getEntityDefinition().getFilter();
if (filter == null || filter.match(child)) {
// XXX add to all candidates!?
if (candidateNode.getValue() == null) {
candidateNode.setAnnotatedParent(source);
source.addAnnotatedChild(candidateNode);
} else {
// Duplicate here, because there is no
// guarantee, that the Duplication
// Visitor will visit candidateNode after
// this node.
SourceNodeImpl duplicateNode = new SourceNodeImpl(candidateNode.getEntityDefinition(), candidateNode.getParent(), false);
duplicateNode.setAnnotatedParent(source);
source.addAnnotatedChild(duplicateNode);
TransformationContext context = candidateNode.getContext();
duplicateNode.setContext(context);
if (context != null) {
context.duplicateContext(candidateNode, duplicateNode, Collections.<Cell>emptySet(), log);
} else {
/*
* Not sure what this really means if we
* get here.
*
* Best guess: Probably that we weren't
* able to determine how the duplication
* of this source can be propagted to
* the target. Thus the duplicated node
* will probably not have any
* connection.
*/
log.warn(log.createMessage("No transformation context for duplicated node of source " + candidateNode.getDefinition().getDisplayName(), null));
}
candidateNode = duplicateNode;
}
// run instance visitor on that annotated child
InstanceVisitor visitor = new InstanceVisitor(child, tree, log);
candidateNode.accept(visitor);
}
}
}
return true;
}
} else
return false;
} else {
Object parentValue = source.getParent().getValue();
if (parentValue == null || !(parentValue instanceof Group)) {
source.setDefined(false);
return false;
} else {
Group parentGroup = (Group) parentValue;
Definition<?> currentDef = source.getDefinition();
Object[] values = parentGroup.getProperty(currentDef.getName());
if (values == null) {
source.setDefined(false);
return false;
}
// check for contexts
EntityDefinition entityDef = source.getEntityDefinition();
// index context
Integer index = AlignmentUtil.getContextIndex(entityDef);
if (index != null) {
// only use the value at the given index, if present
if (index < values.length) {
// annotate with the value at the index
Object value = values[index];
source.setValue(value);
return true;
} else {
source.setDefined(false);
return false;
}
}
// condition context
Condition condition = AlignmentUtil.getContextCondition(entityDef);
if (condition != null) {
if (condition.getFilter() == null) {
// assume exclusion
source.setDefined(false);
return false;
}
// apply condition as filter on values and continue with
// those values
Collection<Object> matchedValues = new ArrayList<Object>();
for (Object value : values) {
// determine parent
Object parent = null;
SourceNode parentNode = source.getParent();
if (parentNode != null && parentNode.isDefined()) {
parent = parentNode.getValue();
}
// test the condition
if (AlignmentUtil.matchCondition(condition, value, parent)) {
matchedValues.add(value);
}
}
values = matchedValues.toArray();
}
// default behavior (default context)
if (values.length >= 1) {
// annotate with the first value
Object value = values[0];
source.setValue(value);
source.setAllValues(values);
} else {
source.setDefined(false);
return false;
}
if (values.length > 1) {
// handle additional values
Object[] leftovers = new Object[values.length - 1];
System.arraycopy(values, 1, leftovers, 0, leftovers.length);
source.setLeftovers(new LeftoversImpl(source, leftovers));
}
return true;
}
}
}
use of eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition in project hale by halestudio.
the class DefaultAlignmentIOTest method testBaseAlignmentSaveLoad.
/**
* Tests base alignment add, save and load.
*
* @throws Exception if an error occurs
*/
@Test
public void testBaseAlignmentSaveLoad() throws Exception {
DefaultAlignment baseAlignment = new DefaultAlignment();
MutableAlignment alignment = new DefaultAlignment();
Schema schema = TestUtil.loadSchema(getClass().getResource("/testdata/simple/t1.xsd").toURI());
Iterator<? extends TypeDefinition> iter = schema.getMappingRelevantTypes().iterator();
TypeDefinition t = iter.next();
if (!t.getName().getLocalPart().equals("T1")) {
t = iter.next();
}
DefaultCell cell1 = new DefaultCell();
cell1.setTransformationIdentifier("trans1");
ListMultimap<String, Type> source = ArrayListMultimap.create();
source.put(null, new DefaultType(new TypeEntityDefinition(t, SchemaSpaceID.SOURCE, null)));
cell1.setSource(source);
ListMultimap<String, Type> target = ArrayListMultimap.create();
target.put(null, new DefaultType(new TypeEntityDefinition(t, SchemaSpaceID.TARGET, null)));
cell1.setTarget(target);
DefaultCell cell2 = new DefaultCell();
cell2.setTransformationIdentifier("trans2");
List<ChildContext> childContext = new ArrayList<ChildContext>();
PropertyDefinition child = DefinitionUtil.getChild(t, new QName("a1")).asProperty();
childContext.add(new ChildContext(child));
ListMultimap<String, Property> source2 = ArrayListMultimap.create();
source2.put(null, new DefaultProperty(new PropertyEntityDefinition(t, childContext, SchemaSpaceID.SOURCE, null)));
cell2.setSource(source2);
ListMultimap<String, Property> target2 = ArrayListMultimap.create();
target2.put(null, new DefaultProperty(new PropertyEntityDefinition(t, childContext, SchemaSpaceID.TARGET, null)));
cell2.setTarget(target2);
// add cell1 to base alignment
baseAlignment.addCell(cell1);
// save base alignment
File baseAlignmentFile = tmp.newFile("alignment_base.xml");
System.out.println(baseAlignmentFile.getAbsolutePath());
saveAlignment(baseAlignment, new BufferedOutputStream(new FileOutputStream(baseAlignmentFile)));
// add as base alignment to extended alignment
addBaseAlignment(alignment, baseAlignmentFile.toURI(), schema, schema);
assertEquals(1, alignment.getBaseAlignments().size());
String usedPrefix = alignment.getBaseAlignments().keySet().iterator().next();
assertEquals(1, alignment.getCells().size());
assertEquals(usedPrefix + ":" + cell1.getId(), alignment.getCells().iterator().next().getId());
// add cell2 to extended alignment
alignment.addCell(cell2);
assertEquals(2, alignment.getCells().size());
assertEquals(1, alignment.getPropertyCells(cell1).size());
// save extended alignment
File alignmentFile = tmp.newFile("alignment_extended.xml");
System.out.println(alignmentFile.getAbsolutePath());
saveAlignment(alignment, new BufferedOutputStream(new FileOutputStream(alignmentFile)));
// load extended
MutableAlignment alignment2 = loadAlignment(new FileInputStream(alignmentFile), schema, schema);
assertEquals(2, alignment2.getCells().size());
assertEquals(1, alignment2.getTypeCells().size());
Cell typeCell = alignment2.getTypeCells().iterator().next();
assertTrue(typeCell instanceof BaseAlignmentCell);
assertEquals(usedPrefix + ":" + cell1.getId(), typeCell.getId());
assertEquals(1, alignment2.getPropertyCells(typeCell).size());
assertFalse(alignment2.getPropertyCells(typeCell).iterator().next() instanceof BaseAlignmentCell);
}
Aggregations