use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class PreferredDescriptionPreCommitHookTest method removeFsnFromExistingConcept.
@Test
public void removeFsnFromExistingConcept() throws Exception {
final SnomedConceptDocument concept = concept().build();
final SnomedDescriptionIndexEntry fsn = fsn(concept.getId(), Collections.singletonMap(Concepts.REFSET_LANGUAGE_TYPE_UK, Acceptability.PREFERRED));
initRevisions(docWithDefaults(concept).preferredDescriptions(ImmutableList.of(new SnomedDescriptionFragment(fsn.getId(), fsn.getTypeId(), fsn.getTerm(), Concepts.REFSET_LANGUAGE_TYPE_UK))).build(), fsn);
stageRemove(fsn);
final ConceptChangeProcessor processor = process();
final SnomedConceptDocument expected = docWithDefaults(concept).build();
final Revision actual = Iterables.getOnlyElement(processor.getChangedMappings().values()).getNewRevision();
assertDocEquals(expected, actual);
assertEquals(0, processor.getNewMappings().size());
assertEquals(0, processor.getDeletions().size());
}
use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class TaxonomyPreCommitHookTest method indexOrphanConceptWithIconId_ShouldGetItsIconId.
@Test
public void indexOrphanConceptWithIconId_ShouldGetItsIconId() throws Exception {
final SnomedConceptDocument concept = concept().build();
availableImages.add(concept.getId());
stageNew(concept);
final ConceptChangeProcessor processor = process();
final SnomedConceptDocument expected = docWithDefaults(concept).iconId(concept.getId()).build();
final Revision actual = Iterables.getOnlyElement(processor.getNewMappings().values());
assertDocEquals(expected, actual);
assertEquals(0, processor.getChangedMappings().size());
assertEquals(0, processor.getDeletions().size());
}
use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class TaxonomyPreCommitHookTest method indexOrphanConcept_ShouldFillDefaultsForDerivedFields.
@Test
public void indexOrphanConcept_ShouldFillDefaultsForDerivedFields() throws Exception {
final SnomedConceptDocument concept = concept().build();
stageNew(concept);
final ConceptChangeProcessor processor = process();
final SnomedConceptDocument expected = docWithDefaults(concept).build();
final Revision actual = Iterables.getOnlyElement(processor.getNewMappings().values());
assertDocEquals(expected, actual);
assertEquals(0, processor.getChangedMappings().size());
assertEquals(0, processor.getDeletions().size());
}
use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class ConceptChangeProcessor method update.
/*
* Updates already existing concept document with changes from concept and the current revision.
* New concepts does not have currentRevision and dirty concepts may not have a loaded Concept CDOObject,
* therefore both can be null, but not at the same time.
* In case of new objects the Concept object should not be null, in case of dirty, the currentVersion should not be null,
* but there can be a dirty concept if a property changed on it.
* We will use whatever we actually have locally to compute the new revision.
*/
private void update(SnomedConceptDocument.Builder doc, List<SnomedDescriptionFragment> preferredDescriptions, @Nullable SnomedConceptDocument newOrDirtyRevision, SnomedConceptDocument cleanRevision) {
checkArgument(newOrDirtyRevision != null || cleanRevision != null, "Either the newOrDirtyRevision is null or the cleanRevision but not both");
final String id = newOrDirtyRevision != null ? newOrDirtyRevision.getId() : cleanRevision.getId();
final long idLong = Long.parseLong(id);
final boolean active = newOrDirtyRevision != null ? newOrDirtyRevision.isActive() : cleanRevision.isActive();
if (newOrDirtyRevision != null) {
doc.active(active).released(newOrDirtyRevision.isReleased()).effectiveTime(newOrDirtyRevision.getEffectiveTime()).moduleId(newOrDirtyRevision.getModuleId()).exhaustive(newOrDirtyRevision.isExhaustive()).definitionStatusId(newOrDirtyRevision.getDefinitionStatusId()).refSetType(newOrDirtyRevision.getRefSetType()).referencedComponentType(newOrDirtyRevision.getReferencedComponentType()).mapTargetComponentType(newOrDirtyRevision.getMapTargetComponentType()).doi(doiData.getDoiScore(idLong));
} else {
doc.active(active).released(cleanRevision.isReleased()).effectiveTime(cleanRevision.getEffectiveTime()).moduleId(cleanRevision.getModuleId()).exhaustive(cleanRevision.isExhaustive()).definitionStatusId(cleanRevision.getDefinitionStatusId()).refSetType(cleanRevision.getRefSetType()).referencedComponentType(cleanRevision.getReferencedComponentType()).mapTargetComponentType(cleanRevision.getMapTargetComponentType()).doi(doiData.getDoiScore(idLong));
}
/*
* Extract semantic tags from active FSNs received in preferredDescriptions (these are expected to be preferred in at
* least one language reference set).
*/
final SortedSet<String> semanticTags = preferredDescriptions.stream().filter(f -> Concepts.FULLY_SPECIFIED_NAME.equals(f.getTypeId())).map(f -> SnomedDescriptionIndexEntry.extractSemanticTag(f.getTerm())).filter(semanticTag -> !semanticTag.isEmpty()).collect(Collectors.toCollection(TreeSet::new));
final boolean inStated = statedTaxonomy.getNewTaxonomy().containsNode(idLong);
final boolean inInferred = inferredTaxonomy.getNewTaxonomy().containsNode(idLong);
if (inStated || inInferred) {
iconId.update(id, Iterables.getFirst(semanticTags, ""), active, doc);
}
if (inStated) {
stated.update(id, doc);
}
if (inInferred) {
inferred.update(id, doc);
}
final Collection<String> currentMemberOf = cleanRevision == null ? Collections.emptySet() : cleanRevision.getMemberOf();
final Collection<String> currentActiveMemberOf = cleanRevision == null ? Collections.emptySet() : cleanRevision.getActiveMemberOf();
new ReferenceSetMembershipUpdater(referringRefSets.removeAll(id), currentMemberOf, currentActiveMemberOf).update(doc);
doc.semanticTags(semanticTags);
doc.preferredDescriptions(preferredDescriptions);
}
use of com.b2international.snowowl.snomed.datastore.index.entry.SnomedConceptDocument in project snow-owl by b2ihealthcare.
the class ConceptChangeProcessor method process.
@Override
public void process(StagingArea staging, RevisionSearcher searcher) throws IOException {
// collect member changes
this.referringRefSets = HashMultimap.create(memberChangeProcessor.process(staging, searcher));
processNewConcepts(staging);
// collect dirty concepts that require additional properties to be set for index
final Map<String, RevisionDiff> dirtyConceptDiffsById = Maps.uniqueIndex(staging.getChangedRevisions(SnomedConceptDocument.class).iterator(), diff -> diff.newRevision.getId());
final Set<String> dirtyConceptIds = collectDirtyConceptIds(staging);
// remaining new/dirty/detached descriptions should be properly processed for preferredDescriptions field
final Map<String, SnomedDescriptionIndexEntry> affectedDescriptionsById = getDescriptionDocuments(staging, searcher);
final Multimap<String, SnomedDescriptionIndexEntry> affectedDescriptionsByConcept = Multimaps.index(affectedDescriptionsById.values(), SnomedDescriptionIndexEntry::getConceptId);
dirtyConceptIds.addAll(affectedDescriptionsByConcept.keySet());
// remove all new/detached concept IDs, we've already processed them
staging.getRemovedObjects(SnomedConceptDocument.class).map(SnomedConceptDocument::getId).forEach(dirtyConceptIds::remove);
staging.getNewObjects(SnomedConceptDocument.class).map(SnomedConceptDocument::getId).forEach(dirtyConceptIds::remove);
if (!dirtyConceptIds.isEmpty()) {
final Map<ObjectId, RevisionDiff> changedRevisions = staging.getChangedRevisions();
// fetch all dirty concept documents by their ID
final Set<String> missingCurrentConceptIds = dirtyConceptIds.stream().filter(id -> !changedRevisions.containsKey(ObjectId.of(SnomedConcept.TYPE, id))).collect(Collectors.toSet());
final Map<String, SnomedConceptDocument> currentConceptDocumentsById = newHashMap(Maps.uniqueIndex(searcher.get(SnomedConceptDocument.class, missingCurrentConceptIds), Revision::getId));
dirtyConceptIds.stream().map(id -> ObjectId.of(SnomedConcept.TYPE, id)).filter(changedRevisions::containsKey).map(changedRevisions::get).map(diff -> (SnomedConceptDocument) diff.oldRevision).forEach(doc -> currentConceptDocumentsById.put(doc.getId(), doc));
// update dirty concepts
for (final String id : dirtyConceptIds) {
final SnomedConceptDocument concept = dirtyConceptDiffsById.containsKey(id) ? (SnomedConceptDocument) dirtyConceptDiffsById.get(id).newRevision : null;
final SnomedConceptDocument currentDoc = currentConceptDocumentsById.get(id);
if (currentDoc == null) {
throw new IllegalStateException("Current concept revision should not be null for: " + id);
}
final Builder doc = SnomedConceptDocument.builder(currentDoc);
final Collection<SnomedDescriptionIndexEntry> affectedDescriptions = affectedDescriptionsByConcept.get(id);
if (!affectedDescriptions.isEmpty()) {
final Map<String, SnomedDescriptionFragment> updatedPreferredDescriptions = newHashMap(Maps.uniqueIndex(currentDoc.getPreferredDescriptions(), SnomedDescriptionFragment::getId));
// add new/dirty fragments if they are preferred and active terms
for (SnomedDescriptionIndexEntry affectedDescription : affectedDescriptions) {
if (staging.isNew(affectedDescription) || staging.isChanged(affectedDescription)) {
updatedPreferredDescriptions.remove(affectedDescription.getId());
if (affectedDescription.isActive() && !getPreferredLanguageMembers(affectedDescription).isEmpty()) {
updatedPreferredDescriptions.put(affectedDescription.getId(), toDescriptionFragment(affectedDescription));
}
}
}
// remove deleted descriptions
for (SnomedDescriptionIndexEntry affectedDescription : affectedDescriptions) {
if (staging.isRemoved(affectedDescription)) {
updatedPreferredDescriptions.remove(affectedDescription.getId());
}
}
final List<SnomedDescriptionFragment> preferredDescriptions = updatedPreferredDescriptions.values().stream().sorted(DESCRIPTION_FRAGMENT_ORDER).collect(Collectors.toList());
update(doc, preferredDescriptions, concept, currentDoc);
} else {
update(doc, currentDoc.getPreferredDescriptions(), concept, currentDoc);
}
stageChange(currentDoc, doc.build());
}
}
}
Aggregations