use of com.b2international.snowowl.core.events.bulk.BulkRequestBuilder in project snow-owl by b2ihealthcare.
the class SnomedConcreteDomainImportPostProcessor method postProcess.
@Override
public void postProcess(final BranchContext context, String userId, Logger logger) {
final SnomedCoreConfiguration config = context.service(SnomedCoreConfiguration.class);
if (!config.isConcreteDomainSupported()) {
return;
}
List<RequestBuilder<TransactionContext, ?>> requests = newArrayList();
if (!conceptExists(config.getConcreteDomainTypeRefsetIdentifier(), context)) {
// create module
createConcept(context, logger, MODULE_B2I_EXTENSION, B2I_MODULE_FSN, B2I_MODULE_PT, MODULE_ROOT, requests);
// create defining type refset concept
createConcept(context, logger, REFSET_DEFINING_TYPE, DEFINING_TYPE_REFSET_FSN, DEFINING_TYPE_REFSET_PT, REFSET_ROOT_CONCEPT, requests);
// create concrete domain type refset concept
createConcept(context, logger, config.getConcreteDomainTypeRefsetIdentifier(), CONCRETE_DOMAIN_TYPE_REFSET_FSN, CONCRETE_DOMAIN_TYPE_REFSET_PT, REFSET_DEFINING_TYPE, requests);
// create measurement type concrete domain refset concept
createConcept(context, logger, REFSET_MEASUREMENT_TYPE, MEASUREMENT_TYPE_REFSET_FSN, MEASUREMENT_TYPE_REFSET_PT, config.getConcreteDomainTypeRefsetIdentifier(), requests);
}
// create boolean concrete domain refset identifier concept and refset
createRefsetAndConcept(context, logger, config.getBooleanDatatypeRefsetIdentifier(), BOOLEAN_DATATYPE_REFSET_FSN, BOOLEAN_DATATYPE_REFSET_PT, config.getConcreteDomainTypeRefsetIdentifier(), requests);
// create string concrete domain refset identifier concept and refset
createRefsetAndConcept(context, logger, config.getStringDatatypeRefsetIdentifier(), STRING_DATATYPE_REFSET_FSN, STRING_DATATYPE_REFSET_PT, config.getConcreteDomainTypeRefsetIdentifier(), requests);
// create date-time concrete domain refset identifier concept and refset
createRefsetAndConcept(context, logger, config.getDatetimeDatatypeRefsetIdentifier(), DATETIME_DATATYPE_REFSET_FSN, DATETIME_DATATYPE_REFSET_PT, config.getConcreteDomainTypeRefsetIdentifier(), requests);
// create integer concrete domain refset identifier concept and refset
createRefsetAndConcept(context, logger, config.getIntegerDatatypeRefsetIdentifier(), INTEGER_DATATYPE_REFSET_FSN, INTEGER_DATATYPE_REFSET_PT, REFSET_MEASUREMENT_TYPE, requests);
// create float concrete domain refset identifier concept and refset
createRefsetAndConcept(context, logger, config.getFloatDatatypeRefsetIdentifier(), FLOAT_DATATYPE_REFSET_FSN, FLOAT_DATATYPE_REFSET_PT, REFSET_MEASUREMENT_TYPE, requests);
if (!requests.isEmpty()) {
try {
final BulkRequestBuilder<TransactionContext> bulkRequest = BulkRequest.create();
requests.forEach(bulkRequest::add);
SnomedRequests.prepareCommit().setBody(bulkRequest).setAuthor(userId).setCommitComment("Import post processor created concrete domain reference sets").setParentContextDescription(DatastoreLockContextDescriptions.IMPORT).build().execute(context);
} catch (final Exception e) {
logger.error("Caught exception while creating concrete domain reference sets in {}", getClass().getSimpleName(), e);
}
}
}
use of com.b2international.snowowl.core.events.bulk.BulkRequestBuilder 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