use of com.b2international.snowowl.snomed.datastore.id.assigner.SnomedNamespaceAndModuleAssigner in project snow-owl by b2ihealthcare.
the class SaveJobRequest method createNamespaceAndModuleAssigner.
private SnomedNamespaceAndModuleAssigner createNamespaceAndModuleAssigner(final BranchContext context) {
// Override assigner type if given
final String selectedType;
if (assignerType != null) {
selectedType = assignerType;
} else {
final TerminologyResource resource = context.service(TerminologyResource.class);
selectedType = (String) resource.getSettings().getOrDefault(NAMESPACE_AND_MODULE_ASSIGNER, DEFAULT_NAMESPACE_AND_MODULE_ASSIGNER);
}
final SnomedNamespaceAndModuleAssigner assigner = SnomedNamespaceAndModuleAssigner.create(context, selectedType, moduleId, namespace);
LOG.info("Reasoner service will use {} for relationship/concrete domain namespace and module assignment.", assigner);
return assigner;
}
use of com.b2international.snowowl.snomed.datastore.id.assigner.SnomedNamespaceAndModuleAssigner in project snow-owl by b2ihealthcare.
the class SaveJobRequest method applyChanges.
private void applyChanges(final SubMonitor subMonitor, final BranchContext context, final BulkRequestBuilder<TransactionContext> bulkRequestBuilder) {
final SnomedNamespaceAndModuleAssigner assigner = createNamespaceAndModuleAssigner(context);
final Set<String> conceptIdsToSkip = mergeEquivalentConcepts(context, bulkRequestBuilder, assigner);
applyRelationshipChanges(context, bulkRequestBuilder, assigner, conceptIdsToSkip);
if (handleConcreteDomains) {
// CD member support in configuration overrides the flag on the save request
final SnomedCoreConfiguration snomedCoreConfiguration = context.service(SnomedCoreConfiguration.class);
if (snomedCoreConfiguration.isConcreteDomainSupported()) {
applyConcreteDomainChanges(context, bulkRequestBuilder, assigner, conceptIdsToSkip);
}
}
}
use of com.b2international.snowowl.snomed.datastore.id.assigner.SnomedNamespaceAndModuleAssigner in project snow-owl by b2ihealthcare.
the class SaveJobRequest method mergeEquivalentConcepts.
private Set<String> mergeEquivalentConcepts(final BranchContext context, final BulkRequestBuilder<TransactionContext> bulkRequestBuilder, final SnomedNamespaceAndModuleAssigner assigner) {
if (!fixEquivalences) {
return Collections.emptySet();
}
// XXX: Restrict merging to active components only
final String expand = "equivalentConcepts(expand(" + "descriptions(active:true)," + "relationships(active:true)," + "inboundRelationships(active:true)," + "members(active:true)))";
final Multimap<SnomedConcept, SnomedConcept> equivalentConcepts = HashMultimap.create();
ClassificationRequests.prepareSearchEquivalentConceptSet().setLimit(SCROLL_LIMIT).setExpand(expand).filterByClassificationId(classificationId).stream(context).flatMap(EquivalentConceptSets::stream).filter(equivalentSet -> !equivalentSet.isUnsatisfiable()).forEach(equivalentSet -> {
final List<SnomedConcept> conceptsToRemove = newArrayList(equivalentSet.getEquivalentConcepts());
final SnomedConcept conceptToKeep = conceptsToRemove.remove(0);
equivalentConcepts.putAll(conceptToKeep, conceptsToRemove);
});
// Are there any equivalent concepts present? or Were all equivalent concepts unsatisfiable?
if (equivalentConcepts.isEmpty()) {
return Collections.emptySet();
}
IEquivalentConceptMerger merger = Extensions.getFirstPriorityExtension(IEquivalentConceptMerger.EXTENSION_POINT, IEquivalentConceptMerger.class);
if (merger == null) {
merger = new IEquivalentConceptMerger.Default();
}
final String mergerName = merger.getClass().getSimpleName();
LOG.info("Reasoner service will use {} for equivalent concept merging.", mergerName);
final Set<String> conceptIdsToSkip = merger.merge(equivalentConcepts);
final Set<String> conceptIdsToKeep = equivalentConcepts.keySet().stream().map(SnomedConcept::getId).collect(Collectors.toSet());
// Prepare to provide namespace-module for inbound relationship source concepts as well
final Set<String> relationshipChangeConceptIds = newHashSet(conceptIdsToKeep);
// Add source concepts on new/about to be inactivated inbound relationships, pointing to "kept" concepts
for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
for (final SnomedRelationship relationship : conceptToKeep.getInboundRelationships()) {
if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
relationshipChangeConceptIds.add(relationship.getSourceId());
} else if (!relationship.isActive()) {
relationshipChangeConceptIds.add(relationship.getSourceId());
}
}
}
assigner.collectRelationshipNamespacesAndModules(relationshipChangeConceptIds, context);
for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
for (final SnomedRelationship relationship : conceptToKeep.getInboundRelationships()) {
// Already handled as another concept's outbound relationship
if (relationship.getId() == null) {
continue;
}
if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
relationship.setId(null);
addComponent(bulkRequestBuilder, assigner, relationship);
} else if (!relationship.isActive()) {
removeOrDeactivate(bulkRequestBuilder, assigner, relationship);
}
}
for (final SnomedRelationship relationship : conceptToKeep.getRelationships()) {
// Already handled as another concept's inbound relationship
if (relationship.getId() == null) {
continue;
}
if (relationship.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
relationship.setId(null);
addComponent(bulkRequestBuilder, assigner, relationship);
} else if (!relationship.isActive()) {
removeOrDeactivate(bulkRequestBuilder, assigner, relationship);
}
}
}
// CD members are always "outbound", however, so the concept SCTID set can be reduced
assigner.clear();
assigner.collectConcreteDomainModules(conceptIdsToKeep, context);
for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
for (final SnomedReferenceSetMember member : conceptToKeep.getMembers()) {
if (member.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
member.setId(null);
addComponent(bulkRequestBuilder, assigner, member);
} else if (member.getId().startsWith(IEquivalentConceptMerger.PREFIX_UPDATED)) {
// Trim the prefix from the ID to restore its original form
member.setId(member.getId().substring(IEquivalentConceptMerger.PREFIX_UPDATED.length()));
bulkRequestBuilder.add(member.toUpdateRequest());
} else if (!member.isActive()) {
removeOrDeactivate(bulkRequestBuilder, assigner, member);
}
}
}
// Descriptions are also "outbound"
assigner.clear();
assigner.collectRelationshipNamespacesAndModules(conceptIdsToKeep, context);
for (final SnomedConcept conceptToKeep : equivalentConcepts.keySet()) {
for (final SnomedDescription description : conceptToKeep.getDescriptions()) {
if (description.getId().startsWith(IEquivalentConceptMerger.PREFIX_NEW)) {
description.setId(null);
addComponent(bulkRequestBuilder, assigner, description);
} else if (description.getId().startsWith(IEquivalentConceptMerger.PREFIX_UPDATED)) {
// Trim the prefix from the ID to restore its original form
description.setId(description.getId().substring(IEquivalentConceptMerger.PREFIX_UPDATED.length()));
bulkRequestBuilder.add(description.toUpdateRequest());
} else if (!description.isActive()) {
removeOrDeactivate(bulkRequestBuilder, assigner, description);
}
}
}
// Inactivation of "removed" concepts also requires modules to be collected according to the assigner rules
assigner.clear();
assigner.collectRelationshipNamespacesAndModules(conceptIdsToSkip, context);
for (final SnomedConcept conceptToRemove : equivalentConcepts.values()) {
// Check if the concept needs to be removed or deactivated
if (!conceptToRemove.isActive()) {
removeOrDeactivate(bulkRequestBuilder, assigner, conceptToRemove);
}
}
assigner.clear();
return conceptIdsToSkip;
}
Aggregations