<commit_before>package com.nedap.archie.flattener;

import com.google.common.collect.Sets;
import com.nedap.archie.aom.Archetype;
import com.nedap.archie.aom.OperationalTemplate;
import com.nedap.archie.aom.terminology.ArchetypeTerm;
import com.nedap.archie.aom.terminology.ArchetypeTerminology;
import com.nedap.archie.aom.terminology.ValueSet;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class TerminologyFlattener {

    protected static void flattenTerminology(Archetype result, Archetype child) {

        ArchetypeTerminology resultTerminology = result.getTerminology();
        ArchetypeTerminology childTerminology = child.getTerminology();

        flattenTerminologyDefinitions(resultTerminology.getTermDefinitions(), childTerminology.getTermDefinitions());
        flattenTerminologyDefinitions(resultTerminology.getTerminologyExtracts(), childTerminology.getTerminologyExtracts());
        flattenTerminologyDefinitions(resultTerminology.getTermBindings(), childTerminology.getTermBindings());
        resultTerminology.setDifferential(false);//TODO: correct?

        Map<String, ValueSet> childValueSets = childTerminology.getValueSets();
        Map<String, ValueSet> resultValueSets = resultTerminology.getValueSets();

        flattenValueSets(childValueSets, resultValueSets);
    }

    /**
     * Gets a term definition for a nodeId. If a direct match is not found, try to find for matching node ids - so looking for id1.1.1 will then find id1.1 if id1.1.1 is not defined
     * @param termDefinitions
     * @param language
     * @param nodeId
     * @return
     */
    protected static ArchetypeTerm getTerm(Map<String, Map<String, ArchetypeTerm>> termDefinitions, String language, String nodeId) {
        Map<String, ArchetypeTerm> translations = termDefinitions.get(language);
        ArchetypeTerm term = translations.get(nodeId);
        if(term == null) {
            for(Map.Entry<String, ArchetypeTerm> entry: translations.entrySet()) {
                if(nodeId.startsWith(entry.getKey() + ".")) {
                    return entry.getValue();
                }
            }

        }
        return term;
    }

    private static void flattenValueSets(Map<String, ValueSet> childValueSets, Map<String, ValueSet> resultValueSets) {
        for(String key:childValueSets.keySet()) {
            ValueSet childValueSet = childValueSets.get(key);
            ValueSet overriddenValueSet = findMatchingValueSet(resultValueSets, key);
            if(overriddenValueSet == null) {
                resultValueSets.put(key, childValueSet);
            } else {
                //we could just set the overridden value set to the new value and remove the old one
                //but that would mean you could also add codes in a specialized archetype- and you cannot
                Set<String> newMembers = new LinkedHashSet<>();
                for(String member: overriddenValueSet.getMembers()) {
                    if(childValueSet.getMembers().contains(member)) {<commit_msg>Fix TerminologyFlattener.getTerm()<commit_after>package com.nedap.archie.flattener;

import com.google.common.collect.Sets;
import com.nedap.archie.aom.Archetype;
import com.nedap.archie.aom.OperationalTemplate;
import com.nedap.archie.aom.terminology.ArchetypeTerm;
import com.nedap.archie.aom.terminology.ArchetypeTerminology;
import com.nedap.archie.aom.terminology.ValueSet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class TerminologyFlattener {

    protected static void flattenTerminology(Archetype result, Archetype child) {

        ArchetypeTerminology resultTerminology = result.getTerminology();
        ArchetypeTerminology childTerminology = child.getTerminology();

        flattenTerminologyDefinitions(resultTerminology.getTermDefinitions(), childTerminology.getTermDefinitions());
        flattenTerminologyDefinitions(resultTerminology.getTerminologyExtracts(), childTerminology.getTerminologyExtracts());
        flattenTerminologyDefinitions(resultTerminology.getTermBindings(), childTerminology.getTermBindings());
        resultTerminology.setDifferential(false);//TODO: correct?

        Map<String, ValueSet> childValueSets = childTerminology.getValueSets();
        Map<String, ValueSet> resultValueSets = resultTerminology.getValueSets();

        flattenValueSets(childValueSets, resultValueSets);
    }

    /**
     * Gets a term definition for a nodeId. If a direct match is not found, try to find for matching node ids - so looking for id1.1.1 will then find id1.1 if id1.1.1 is not defined
     * @param termDefinitions
     * @param language
     * @param nodeId
     * @return
     */
    protected static ArchetypeTerm getTerm(Map<String, Map<String, ArchetypeTerm>> termDefinitions, String language, String nodeId) {
        Map<String, ArchetypeTerm> translations = termDefinitions.get(language);
        ArchetypeTerm term = translations.get(nodeId);
        Map<String, ArchetypeTerm> foundTerms = new LinkedHashMap<>();
        if(term == null) {
            for(Map.Entry<String, ArchetypeTerm> entry: translations.entrySet()) {
                if(nodeId.startsWith(entry.getKey() + ".")) {
                    foundTerms.put(nodeId, entry.getValue());
                }
            }
            //get the longest matching node id
            List<String> foundNodeIds = new ArrayList(foundTerms.keySet());
            Collections.sort(foundNodeIds, Comparator.comparingInt((id) -> id.length()));
            return foundTerms.get(foundNodeIds.get(foundNodeIds.size()-1));

        }
        return term;
    }

    private static void flattenValueSets(Map<String, ValueSet> childValueSets, Map<String, ValueSet> resultValueSets) {
        for(String key:childValueSets.keySet()) {
            ValueSet childValueSet = childValueSets.get(key);
            ValueSet overriddenValueSet = findMatchingValueSet(resultValueSets, key);
            if(overriddenValueSet == null) {
                resultValueSets.put(key, childValueSet);
            } else {
                //we could just set the overridden value set to the new value and remove the old one
                //but that would mean you could also add codes in a specialized archetype- and you cannot
                Set<String> newMembers = new LinkedHashSet<>();
                for(String member: overriddenValueSet.getMembers()) {
                    if(childValueSet.getMembers().contains(member)) {
{'fraction_non_alphanumeric': 0.09323173464813984, 'fraction_numerical': 0.0025399671298371434, 'mean_word_length': 3.3298835705045278, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4264417', 'n_tokens_mistral': 1906, 'n_tokens_neox': 1848, 'n_words': 413}