use of com.b2international.index.revision.StagingArea.RevisionPropertyDiff in project snow-owl by b2ihealthcare.
the class Taxonomies method updateTaxonomy.
private static TaxonomyGraphStatus updateTaxonomy(RevisionSearcher searcher, SnomedOWLExpressionConverter expressionConverter, StagingArea staging, TaxonomyGraph graphToUpdate, String characteristicTypeId) throws IOException {
LOGGER.trace("Processing changes taxonomic information.");
staging.getNewObjects(SnomedRelationshipIndexEntry.class).filter(relationship -> characteristicTypeId.equals(relationship.getCharacteristicTypeId())).forEach(newRelationship -> updateEdge(newRelationship, graphToUpdate));
final Set<String> relationshipsToExcludeFromReactivatedConcepts = newHashSet();
staging.getChangedRevisions(SnomedRelationshipIndexEntry.class).map(diff -> (SnomedRelationshipIndexEntry) diff.newRevision).filter(relationship -> characteristicTypeId.equals(relationship.getCharacteristicTypeId())).forEach(dirtyRelationship -> {
relationshipsToExcludeFromReactivatedConcepts.add(dirtyRelationship.getId());
updateEdge(dirtyRelationship, graphToUpdate);
});
staging.getRemovedObjects(SnomedRelationshipIndexEntry.class).filter(relationship -> characteristicTypeId.equals(relationship.getCharacteristicTypeId())).forEach(relationship -> {
relationshipsToExcludeFromReactivatedConcepts.add(relationship.getId());
graphToUpdate.removeEdge(relationship.getId());
});
if (Concepts.STATED_RELATIONSHIP.equals(characteristicTypeId)) {
staging.getNewObjects(SnomedRefSetMemberIndexEntry.class).filter(member -> SnomedRefSetType.OWL_AXIOM == member.getReferenceSetType()).forEach(member -> updateEdge(member, graphToUpdate, expressionConverter));
staging.getChangedRevisions(SnomedRefSetMemberIndexEntry.class).map(diff -> (SnomedRefSetMemberIndexEntry) diff.newRevision).filter(member -> SnomedRefSetType.OWL_AXIOM == member.getReferenceSetType()).forEach(member -> updateEdge(member, graphToUpdate, expressionConverter));
staging.getRemovedObjects(SnomedRefSetMemberIndexEntry.class).filter(member -> SnomedRefSetType.OWL_AXIOM == member.getReferenceSetType()).map(SnomedRefSetMemberIndexEntry::getId).forEach(graphToUpdate::removeEdge);
}
staging.getNewObjects(SnomedConceptDocument.class).forEach(newConcept -> updateConcept(newConcept, graphToUpdate));
staging.getRemovedObjects(SnomedConceptDocument.class).forEach(concept -> graphToUpdate.removeNode(concept.getId()));
final Set<String> conceptWithPossibleMissingRelationships = newHashSet();
staging.getChangedRevisions(SnomedConceptDocument.class, Collections.singleton(SnomedConceptDocument.Fields.ACTIVE)).forEach(diff -> {
final RevisionPropertyDiff propDiff = diff.getRevisionPropertyDiff(SnomedConceptDocument.Fields.ACTIVE);
final boolean oldValue = Boolean.parseBoolean(propDiff.getOldValue());
final boolean newValue = Boolean.parseBoolean(propDiff.getNewValue());
final String conceptId = diff.newRevision.getId();
if (!oldValue && newValue) {
// make sure the node is part of the new tree
graphToUpdate.addNode(conceptId);
conceptWithPossibleMissingRelationships.add(conceptId);
}
});
if (!conceptWithPossibleMissingRelationships.isEmpty()) {
Hits<String[]> possibleMissingRelationships = searcher.search(Query.select(String[].class).from(SnomedRelationshipIndexEntry.class).fields(SnomedRelationshipIndexEntry.Fields.ID, SnomedRelationshipIndexEntry.Fields.SOURCE_ID, SnomedRelationshipIndexEntry.Fields.DESTINATION_ID).where(Expressions.builder().filter(SnomedRelationshipIndexEntry.Expressions.active()).filter(SnomedRelationshipIndexEntry.Expressions.characteristicTypeId(characteristicTypeId)).filter(SnomedRelationshipIndexEntry.Expressions.typeId(Concepts.IS_A)).filter(SnomedRelationshipIndexEntry.Expressions.sourceIds(conceptWithPossibleMissingRelationships)).mustNot(SnomedRelationshipIndexEntry.Expressions.ids(relationshipsToExcludeFromReactivatedConcepts)).build()).limit(Integer.MAX_VALUE).build());
for (String[] relationship : possibleMissingRelationships) {
graphToUpdate.addNode(relationship[2]);
graphToUpdate.addEdge(relationship[0], Long.parseLong(relationship[1]), new long[] { Long.parseLong(relationship[2]) });
}
}
LOGGER.trace("Rebuilding taxonomic information based on the changes.");
return graphToUpdate.update();
}
use of com.b2international.index.revision.StagingArea.RevisionPropertyDiff in project snow-owl by b2ihealthcare.
the class SnomedRepositoryPreCommitHook method getChangeSetProcessors.
@Override
protected Collection<ChangeSetProcessor> getChangeSetProcessors(StagingArea staging, RevisionSearcher index) throws IOException {
final RepositoryContext context = ClassUtils.checkAndCast(staging.getContext(), RepositoryContext.class);
// initialize OWL Expression converter on the current branch
final SnomedOWLExpressionConverter expressionConverter = new BranchRequest<>(staging.getBranchPath(), branchContext -> {
return new SnomedOWLExpressionConverter(branchContext.inject().bind(RevisionSearcher.class, index).build());
}).execute(context);
final Set<String> statedSourceIds = Sets.newHashSet();
final Set<String> statedDestinationIds = Sets.newHashSet();
final Set<String> inferredSourceIds = Sets.newHashSet();
final Set<String> inferredDestinationIds = Sets.newHashSet();
collectIds(statedSourceIds, statedDestinationIds, staging.getNewObjects(SnomedRelationshipIndexEntry.class), Concepts.STATED_RELATIONSHIP);
collectIds(statedSourceIds, statedDestinationIds, staging.getChangedRevisions(SnomedRelationshipIndexEntry.class).map(diff -> (SnomedRelationshipIndexEntry) diff.newRevision), Concepts.STATED_RELATIONSHIP);
collectIds(inferredSourceIds, inferredDestinationIds, staging.getNewObjects(SnomedRelationshipIndexEntry.class), Concepts.INFERRED_RELATIONSHIP);
collectIds(inferredSourceIds, inferredDestinationIds, staging.getChangedRevisions(SnomedRelationshipIndexEntry.class).map(diff -> (SnomedRelationshipIndexEntry) diff.newRevision), Concepts.INFERRED_RELATIONSHIP);
collectIds(statedSourceIds, statedDestinationIds, staging.getNewObjects(SnomedRefSetMemberIndexEntry.class), expressionConverter);
collectIds(statedSourceIds, statedDestinationIds, staging.getChangedRevisions(SnomedRefSetMemberIndexEntry.class).map(diff -> (SnomedRefSetMemberIndexEntry) diff.newRevision), expressionConverter);
staging.getRemovedObjects(SnomedRelationshipIndexEntry.class).filter(detachedRelationship -> Concepts.IS_A.equals(detachedRelationship.getTypeId())).forEach(detachedRelationship -> {
// XXX: IS A relationships are expected to have a destination ID, not a value
checkState(!detachedRelationship.hasValue(), "IS A relationship found with value: %s", detachedRelationship.getId());
if (Concepts.STATED_RELATIONSHIP.equals(detachedRelationship.getCharacteristicTypeId())) {
statedSourceIds.add(detachedRelationship.getSourceId());
statedDestinationIds.add(detachedRelationship.getDestinationId());
} else if (Concepts.INFERRED_RELATIONSHIP.equals(detachedRelationship.getCharacteristicTypeId())) {
inferredSourceIds.add(detachedRelationship.getSourceId());
inferredDestinationIds.add(detachedRelationship.getDestinationId());
}
});
staging.getRemovedObjects(SnomedRefSetMemberIndexEntry.class).filter(detachedMember -> SnomedRefSetType.OWL_AXIOM == detachedMember.getReferenceSetType()).forEach(detachedOwlMember -> {
collectIds(statedSourceIds, statedDestinationIds, detachedOwlMember, expressionConverter);
});
final LongSet statedConceptIds = PrimitiveSets.newLongOpenHashSet();
final LongSet inferredConceptIds = PrimitiveSets.newLongOpenHashSet();
if (!statedDestinationIds.isEmpty()) {
for (SnomedConceptDocument statedDestinationConcept : index.get(SnomedConceptDocument.class, statedDestinationIds)) {
statedConceptIds.add(Long.parseLong(statedDestinationConcept.getId()));
if (statedDestinationConcept.getStatedParents() != null) {
statedConceptIds.addAll(statedDestinationConcept.getStatedParents());
}
if (statedDestinationConcept.getStatedAncestors() != null) {
statedConceptIds.addAll(statedDestinationConcept.getStatedAncestors());
}
}
}
if (!inferredDestinationIds.isEmpty()) {
for (SnomedConceptDocument inferredDestinationConcept : index.get(SnomedConceptDocument.class, inferredDestinationIds)) {
inferredConceptIds.add(Long.parseLong(inferredDestinationConcept.getId()));
if (inferredDestinationConcept.getParents() != null) {
inferredConceptIds.addAll(inferredDestinationConcept.getParents());
}
if (inferredDestinationConcept.getAncestors() != null) {
inferredConceptIds.addAll(inferredDestinationConcept.getAncestors());
}
}
}
staging.getRemovedObjects(SnomedDescriptionIndexEntry.class).forEach(removedDescription -> {
if (removedDescription.isFsn() && removedDescription.isActive()) {
statedSourceIds.add(removedDescription.getConceptId());
inferredSourceIds.add(removedDescription.getConceptId());
}
});
staging.getChangedRevisions(SnomedDescriptionIndexEntry.class).filter(diff -> ((SnomedDescriptionIndexEntry) diff.newRevision).isFsn()).filter(diff -> diff.hasRevisionPropertyChanges(ACTIVE_AND_TERM_FIELDS)).forEach(diff -> {
SnomedDescriptionIndexEntry newRevision = (SnomedDescriptionIndexEntry) diff.newRevision;
statedSourceIds.add(newRevision.getConceptId());
inferredSourceIds.add(newRevision.getConceptId());
});
staging.getNewObjects(SnomedDescriptionIndexEntry.class).filter(newDescription -> newDescription.isFsn() && newDescription.isActive()).forEach(newDescription -> {
statedSourceIds.add(newDescription.getConceptId());
inferredSourceIds.add(newDescription.getConceptId());
});
if (!statedSourceIds.isEmpty()) {
final Query<SnomedConceptDocument> statedSourceConceptsQuery = Query.select(SnomedConceptDocument.class).where(Expressions.builder().should(SnomedConceptDocument.Expressions.ids(statedSourceIds)).should(SnomedConceptDocument.Expressions.statedParents(statedSourceIds)).should(SnomedConceptDocument.Expressions.statedAncestors(statedSourceIds)).build()).limit(Integer.MAX_VALUE).build();
for (SnomedConceptDocument statedSourceConcept : index.search(statedSourceConceptsQuery)) {
statedConceptIds.add(Long.parseLong(statedSourceConcept.getId()));
if (statedSourceConcept.getStatedParents() != null) {
statedConceptIds.addAll(statedSourceConcept.getStatedParents());
}
if (statedSourceConcept.getStatedAncestors() != null) {
statedConceptIds.addAll(statedSourceConcept.getStatedAncestors());
}
}
}
if (!inferredSourceIds.isEmpty()) {
final Query<SnomedConceptDocument> inferredSourceConceptsQuery = Query.select(SnomedConceptDocument.class).where(Expressions.builder().should(SnomedConceptDocument.Expressions.ids(inferredSourceIds)).should(SnomedConceptDocument.Expressions.parents(inferredSourceIds)).should(SnomedConceptDocument.Expressions.ancestors(inferredSourceIds)).build()).limit(Integer.MAX_VALUE).build();
for (SnomedConceptDocument inferredSourceConcept : index.search(inferredSourceConceptsQuery)) {
inferredConceptIds.add(Long.parseLong(inferredSourceConcept.getId()));
if (inferredSourceConcept.getParents() != null) {
inferredConceptIds.addAll(inferredSourceConcept.getParents());
}
if (inferredSourceConcept.getAncestors() != null) {
inferredConceptIds.addAll(inferredSourceConcept.getAncestors());
}
}
}
staging.getNewObjects(SnomedConceptDocument.class).forEach(newConcept -> {
long longId = Long.parseLong(newConcept.getId());
statedConceptIds.add(longId);
inferredConceptIds.add(longId);
});
// collect all reactivated concepts for the taxonomy to properly re-register them in the tree even if they don't carry stated/inferred information in this commit, but they have something in the index
staging.getChangedRevisions(SnomedConceptDocument.class, Set.of(SnomedRf2Headers.FIELD_ACTIVE)).forEach(diff -> {
RevisionPropertyDiff propertyDiff = diff.getRevisionPropertyDiff(SnomedRf2Headers.FIELD_ACTIVE);
if ("false".equals(propertyDiff.getOldValue()) && "true".equals(propertyDiff.getNewValue())) {
long longId = Long.parseLong(diff.newRevision.getId());
statedConceptIds.add(longId);
inferredConceptIds.add(longId);
}
});
log.trace("Retrieving taxonomic information from store...");
final boolean checkCycles = !(context instanceof Rf2TransactionContext);
final Taxonomy inferredTaxonomy = Taxonomies.inferred(index, expressionConverter, staging, inferredConceptIds, checkCycles);
final Taxonomy statedTaxonomy = Taxonomies.stated(index, expressionConverter, staging, statedConceptIds, checkCycles);
// XXX change processor execution order is important!!!
return List.of(// those values will be used in the ConceptChangeProcessor for example to properly compute the preferredDescriptions derived field
new DescriptionChangeProcessor(), new ConceptChangeProcessor(DoiDataProvider.INSTANCE, SnomedIconProvider.INSTANCE.getAvailableIconIds(), statedTaxonomy, inferredTaxonomy), new RelationshipChangeProcessor());
}
use of com.b2international.index.revision.StagingArea.RevisionPropertyDiff in project snow-owl by b2ihealthcare.
the class ReferringMemberChangeProcessor method process.
public Multimap<String, RefSetMemberChange> process(StagingArea staging, RevisionSearcher searcher) throws IOException {
final Multimap<String, RefSetMemberChange> memberChanges = HashMultimap.create();
// process new members
staging.getNewObjects(SnomedRefSetMemberIndexEntry.class).filter(this::byReferencedComponentType).forEach((newMember) -> {
addChange(memberChanges, newMember, MemberChangeKind.ADDED);
});
// process dirty members
staging.getChangedRevisions(SnomedRefSetMemberIndexEntry.class).filter(diff -> byReferencedComponentType((SnomedRefSetMemberIndexEntry) diff.newRevision)).forEach((diff) -> {
RevisionPropertyDiff propChange = diff.getRevisionPropertyDiff(SnomedRefSetMemberIndexEntry.Fields.ACTIVE);
if (propChange != null) {
addChange(memberChanges, (SnomedRefSetMemberIndexEntry) diff.newRevision, MemberChangeKind.CHANGED);
}
});
// process detached members
staging.getRemovedObjects(SnomedRefSetMemberIndexEntry.class).filter(this::byReferencedComponentType).forEach(doc -> {
final String uuid = doc.getId();
final String referencedComponentId = doc.getReferencedComponentId();
final String refSetId = doc.getRefsetId();
memberChanges.put(referencedComponentId, new RefSetMemberChange(uuid, refSetId, MemberChangeKind.REMOVED, doc.isActive()));
});
return memberChanges;
}
use of com.b2international.index.revision.StagingArea.RevisionPropertyDiff in project snow-owl by b2ihealthcare.
the class ComponentInactivationChangeProcessor method process.
@Override
public void process(StagingArea staging, RevisionSearcher searcher) throws IOException {
// inactivating a concept should inactivate all of its descriptions, relationships, inbound relationships, and members
final Set<String> inactivatedComponentIds = newHashSet();
final Set<String> inactivatedConceptIds = newHashSet();
final Set<String> reactivatedComponentIds = newHashSet();
final Set<String> reactivatedConceptIds = newHashSet();
staging.getChangedRevisions(SnomedComponentDocument.class).filter(diff -> diff.hasRevisionPropertyChanges(SnomedRf2Headers.FIELD_ACTIVE)).filter(diff -> diff.newRevision instanceof SnomedComponentDocument).forEach(diff -> {
RevisionPropertyDiff propDiff = diff.getRevisionPropertyDiff(SnomedRf2Headers.FIELD_ACTIVE);
boolean oldValue = Boolean.parseBoolean(propDiff.getOldValue());
boolean newValue = Boolean.parseBoolean(propDiff.getNewValue());
// inactivation
if (oldValue && !newValue) {
inactivatedComponentIds.add(diff.newRevision.getId());
if (diff.newRevision instanceof SnomedConceptDocument) {
inactivatedConceptIds.add(diff.newRevision.getId());
}
} else if (!oldValue && newValue) {
reactivatedComponentIds.add(diff.newRevision.getId());
if (diff.newRevision instanceof SnomedConceptDocument) {
reactivatedConceptIds.add(diff.newRevision.getId());
}
}
});
processInactivations(staging, searcher, inactivatedConceptIds, inactivatedComponentIds);
processReactivations(staging, searcher, reactivatedConceptIds, reactivatedComponentIds);
}
Aggregations