use of eu.esdihumboldt.hale.common.instance.index.IndexedPropertyValue in project hale by halestudio.
the class IndexJoinIterator method join.
/**
* Joins all direct children of the given type to currentInstances.
*/
@SuppressWarnings("javadoc")
private void join(FamilyInstance[] currentInstances, int currentType) {
// Join all types that are direct children of the last type.
for (int i = currentType + 1; i < joinDefinition.directParent.length; i++) {
if (joinDefinition.directParent[i] == currentType) {
// Get join condition for the direct child type.
Multimap<Integer, JoinCondition> joinConditions = joinDefinition.joinTable.get(i);
// Collect intersection of conditions. null marks beginning
// in contrast to an empty set.
Set<ResolvableInstanceReference> possibleInstances = null;
// ParentType -> JoinConditions
for (Map.Entry<Integer, JoinCondition> joinCondition : joinConditions.entries()) {
PropertyEntityDefinition baseProp = joinCondition.getValue().baseProperty;
QName baseTypeName = baseProp.getType().getName();
List<QName> basePropertyPath = baseProp.getPropertyPath().stream().map(pp -> pp.getChild().getName()).collect(Collectors.toList());
PropertyEntityDefinition joinProp = joinCondition.getValue().joinProperty;
QName joinTypeName = joinProp.getType().getName();
List<QName> joinPropertyPath = joinProp.getPropertyPath().stream().map(pp -> pp.getChild().getName()).collect(Collectors.toList());
List<IndexedPropertyValue> currentValues = index.getInstancePropertyValues(baseTypeName, basePropertyPath, currentInstances[joinCondition.getKey()].getId());
if (currentValues == null || currentValues.isEmpty()) {
possibleInstances = Collections.emptySet();
break;
}
HashSet<ResolvableInstanceReference> matches = new HashSet<ResolvableInstanceReference>();
for (IndexedPropertyValue currentValue : currentValues) {
if (currentValue.getValues() == null || currentValue.getValues().isEmpty()) {
continue;
}
// Find instances that have the current property value
Collection<ResolvableInstanceReference> instancesWithValues = index.getInstancesByValue(joinTypeName, joinPropertyPath, currentValue.getValues());
matches.addAll(instancesWithValues);
}
if (possibleInstances == null) {
possibleInstances = matches;
} else {
// Remove candidates that don't have the current
// property value
Iterator<ResolvableInstanceReference> it = possibleInstances.iterator();
while (it.hasNext()) {
ResolvableInstanceReference cand = it.next();
if (!matches.contains(cand)) {
it.remove();
}
}
}
if (possibleInstances.isEmpty()) {
break;
}
}
if (possibleInstances != null && !possibleInstances.isEmpty()) {
FamilyInstance parent = currentInstances[currentType];
for (ResolvableInstanceReference ref : possibleInstances) {
FamilyInstance child;
child = new FamilyInstanceImpl(ref.resolve());
parent.addChild(child);
currentInstances[i] = child;
join(currentInstances, i);
}
currentInstances[i] = null;
}
}
}
}
Aggregations