<commit_before>/*
 * #%L
 * Protempa UMLS Term Source Backend
 * %%
 * Copyright (C) 2012 - 2013 Emory University
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package org.protempa.backend.tsb.umls;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.arp.javautil.sql.DatabaseAPI;
import org.protempa.MalformedTermIdException;
import org.protempa.Term;
import org.protempa.backend.TermSourceBackendInitializationException;
import org.protempa.TermSourceReadException;
import org.protempa.backend.BackendInstanceSpec;
import org.protempa.backend.AbstractCommonsTermSourceBackend;
import org.protempa.backend.annotations.BackendInfo;
import org.protempa.backend.annotations.BackendProperty;

import edu.emory.cci.aiw.umls.SAB;
import edu.emory.cci.aiw.umls.TerminologyCode;
import edu.emory.cci.aiw.umls.UMLSDatabaseConnection;
import edu.emory.cci.aiw.umls.UMLSNoSuchTermException;
import edu.emory.cci.aiw.umls.UMLSQueryException;
import edu.emory.cci.aiw.umls.UMLSQueryExecutor;
import org.protempa.backend.BackendInitializationException;

@BackendInfo(displayName = "UMLS term source backend")
public final class UMLSTermSourceBackend extends
        AbstractCommonsTermSourceBackend {

    private DatabaseAPI databaseAPI;
    private String databaseId;
    private String username;
    private String password;
    private UMLSQueryExecutor umls;

    public UMLSTermSourceBackend() {

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.protempa.AbstractTermSourceBackend#readTerm(java.lang.String,
     * org.protempa.Terminology)
     */
    @Override
    public Term readTerm(String id) throws TermSourceReadException {
        try {
            Term term = Term.withId(id);

            // SAB sab = sabFromTerm(term);
            SAB sab = SAB.withName(term.getTerminology().getName());
            TerminologyCode code = TerminologyCode.fromStringAndSAB(
                    term.getCode(), sab);
            List<TerminologyCode> children = umls.getChildrenByCode(code);
            List<String> childTerms = new ArrayList<>();
            for (TerminologyCode child : children) {
                childTerms.add(Term.fromTerminologyAndCode(sab.getName(),
                        child.getCode()).getId());
            }
            term.setDirectChildren(childTerms.toArray(new String[childTerms
                    .size()]));
            term.setSemanticType(umls.getSemanticTypeForTerm(code).getType());
            term.setDisplayName(umls.getPreferredName(code));
            term.setDescription(umls.getTermDefinition(code));

            return term;
        } catch (UMLSQueryException ue) {
            throw new TermSourceReadException(ue);
        } catch (MalformedTermIdException te) {
            throw new TermSourceReadException(te);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.protempa.TermSourceBackend#readTerms(java.lang.String[],
     * org.protempa.Terminology)
     */
    @Override
    public Map<String, Term> readTerms(String[] ids)
            throws TermSourceReadException {
        Map<String, Term> result = new HashMap<>();

        for (String id : ids) {
            result.put(id, readTerm(id));
        }

        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.protempa.TermSourceBackend#getDescendents(java.lang.String)
     */
    @Override
    public List<String> getSubsumption(String id)
            throws TermSourceReadException {
        List<String> result = new ArrayList<>();

        try {
            Term term = Term.withId(id);
            SAB sab = SAB.withName(term.getTerminology().getName());
            TerminologyCode code = TerminologyCode.fromStringAndSAB(
                    term.getCode(), sab);

            for (TerminologyCode tc : umls.getTermSubsumption(code)) {
                result.add(Term.fromTerminologyAndCode(tc.getSab().getName(),
                        tc.getCode()).getId());
            }
        } catch (UMLSNoSuchTermException ex) {
            throw new TermSourceReadException(ex);
        } catch (UMLSQueryException ex) {
            throw new TermSourceReadException(ex);
        } catch (MalformedTermIdException ex) {
            throw new TermSourceReadException(ex);
        }

        return result;
    }

    @Override
    public void initialize(BackendInstanceSpec config)
            throws BackendInitializationException {
        super.initialize(config);

        if (this.databaseAPI == null) {
            throw new TermSourceBackendInitializationException(
                    "Term source backend "
                            + nameForErrors()
                            + " requires a Java database API (DRIVERMANAGER or "<commit_msg>collapsed catch statements with identical results<commit_after>/*
 * #%L
 * Protempa UMLS Term Source Backend
 * %%
 * Copyright (C) 2012 - 2013 Emory University
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package org.protempa.backend.tsb.umls;

import edu.emory.cci.aiw.umls.SAB;
import edu.emory.cci.aiw.umls.TerminologyCode;
import edu.emory.cci.aiw.umls.UMLSDatabaseConnection;
import edu.emory.cci.aiw.umls.UMLSQueryException;
import edu.emory.cci.aiw.umls.UMLSQueryExecutor;
import org.arp.javautil.sql.DatabaseAPI;
import org.protempa.MalformedTermIdException;
import org.protempa.Term;
import org.protempa.TermSourceReadException;
import org.protempa.backend.AbstractCommonsTermSourceBackend;
import org.protempa.backend.BackendInitializationException;
import org.protempa.backend.BackendInstanceSpec;
import org.protempa.backend.TermSourceBackendInitializationException;
import org.protempa.backend.annotations.BackendInfo;
import org.protempa.backend.annotations.BackendProperty;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@BackendInfo(displayName = "UMLS term source backend")
public final class UMLSTermSourceBackend extends
        AbstractCommonsTermSourceBackend {

    private DatabaseAPI databaseAPI;
    private String databaseId;
    private String username;
    private String password;
    private UMLSQueryExecutor umls;

    public UMLSTermSourceBackend() {

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.protempa.AbstractTermSourceBackend#readTerm(java.lang.String,
     * org.protempa.Terminology)
     */
    @Override
    public Term readTerm(String id) throws TermSourceReadException {
        try {
            Term term = Term.withId(id);

            // SAB sab = sabFromTerm(term);
            SAB sab = SAB.withName(term.getTerminology().getName());
            TerminologyCode code = TerminologyCode.fromStringAndSAB(
                    term.getCode(), sab);
            List<TerminologyCode> children = umls.getChildrenByCode(code);
            List<String> childTerms = new ArrayList<>();
            for (TerminologyCode child : children) {
                childTerms.add(Term.fromTerminologyAndCode(sab.getName(),
                        child.getCode()).getId());
            }
            term.setDirectChildren(childTerms.toArray(new String[childTerms
                    .size()]));
            term.setSemanticType(umls.getSemanticTypeForTerm(code).getType());
            term.setDisplayName(umls.getPreferredName(code));
            term.setDescription(umls.getTermDefinition(code));

            return term;
        } catch (UMLSQueryException | MalformedTermIdException ue) {
            throw new TermSourceReadException(ue);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.protempa.TermSourceBackend#readTerms(java.lang.String[],
     * org.protempa.Terminology)
     */
    @Override
    public Map<String, Term> readTerms(String[] ids)
            throws TermSourceReadException {
        Map<String, Term> result = new HashMap<>();

        for (String id : ids) {
            result.put(id, readTerm(id));
        }

        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.protempa.TermSourceBackend#getDescendents(java.lang.String)
     */
    @Override
    public List<String> getSubsumption(String id)
            throws TermSourceReadException {
        List<String> result = new ArrayList<>();

        try {
            Term term = Term.withId(id);
            SAB sab = SAB.withName(term.getTerminology().getName());
            TerminologyCode code = TerminologyCode.fromStringAndSAB(
                    term.getCode(), sab);

            for (TerminologyCode tc : umls.getTermSubsumption(code)) {
                result.add(Term.fromTerminologyAndCode(tc.getSab().getName(),
                        tc.getCode()).getId());
            }
        } catch (MalformedTermIdException | UMLSQueryException ex) {
            throw new TermSourceReadException(ex);
        }

        return result;
    }

    @Override
    public void initialize(BackendInstanceSpec config)
            throws BackendInitializationException {
        super.initialize(config);

        if (this.databaseAPI == null) {
            throw new TermSourceBackendInitializationException(
                    "Term source backend "
                            + nameForErrors()
                            + " requires a Java database API (DRIVERMANAGER or "
{'fraction_non_alphanumeric': 0.09541763341067286, 'fraction_numerical': 0.002320185614849188, 'mean_word_length': 2.6400422237860663, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '4944703', 'n_tokens_mistral': 2994, 'n_tokens_neox': 2934, 'n_words': 633}