org.obiba.opal.core.service.TaxonomyServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.obiba.opal.core.service.TaxonomyServiceImpl.java

Source

/*
 * Copyright (c) 2013 OBiBa. All rights reserved.
 *
 * This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.obiba.opal.core.service;

import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.validation.constraints.NotNull;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.obiba.opal.core.cfg.NoSuchTaxonomyException;
import org.obiba.opal.core.cfg.NoSuchVocabularyException;
import org.obiba.opal.core.cfg.TaxonomyService;
import org.obiba.opal.core.domain.taxonomy.Taxonomy;
import org.obiba.opal.core.domain.taxonomy.Vocabulary;
import org.obiba.opal.core.runtime.OpalRuntime;
import org.obiba.opal.core.support.yaml.TaxonomyYaml;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;

@Component
public class TaxonomyServiceImpl implements TaxonomyService {

    @Autowired
    private OpalRuntime opalRuntime;

    @NotNull
    @Value("${org.obiba.opal.taxonomies}")
    private String taxonomyReferences;

    @Autowired
    private TaxonomyPersistenceStrategy taxonomyPersistence;

    private static final Logger log = LoggerFactory.getLogger(TaxonomyServiceImpl.class);

    private static final String MLSTRM_USER = "maelstrom-research";

    private static final String TAXONOMY_YAML = "taxonomy.yml";

    private static final String GITHUB_URL = "https://raw.githubusercontent.com";

    private List<Taxonomy> taxonomies = Lists.newArrayList();

    @Override
    @PostConstruct
    public void start() {
        taxonomies = Collections.synchronizedList(Lists.newArrayList(taxonomyPersistence.readTaxonomies()));
        importDefault(false);
        sort();
    }

    @Override
    public void stop() {
    }

    @Override
    public void importDefault() {
        importDefault(true);
    }

    @Override
    public Taxonomy importGitHubTaxonomy(@NotNull String username, @NotNull String repo, @Nullable String ref,
            @NotNull String taxonomyFile) {
        return importGitHubTaxonomy(username, repo, ref, taxonomyFile, true);
    }

    @Override
    public Taxonomy importFileTaxonomy(@NotNull String file) throws FileSystemException {
        FileObject fileObj = resolveFileInFileSystem(file);

        try {
            InputStream input = fileObj.getContent().getInputStream();
            TaxonomyYaml yaml = new TaxonomyYaml();
            Taxonomy taxonomy = yaml.load(input);
            saveTaxonomy(taxonomy);
            return taxonomy;
        } catch (Exception e) {
            log.error("Failed loading taxonomy from: " + file, e);
        }

        return null;
    }

    @Override
    public Iterable<Taxonomy> getTaxonomies() {
        return taxonomies;
    }

    @Override
    public boolean hasTaxonomy(@NotNull String name) {
        for (Taxonomy taxonomy : taxonomies) {
            if (taxonomy.getName().equals(name))
                return true;
        }
        return false;
    }

    @Nullable
    @Override
    public Taxonomy getTaxonomy(@NotNull String name) {
        for (Taxonomy taxonomy : taxonomies) {
            if (taxonomy.getName().equals(name))
                return taxonomy;
        }
        return null;
    }

    @Override
    public void saveTaxonomy(@NotNull Taxonomy taxonomy) {
        synchronized (this) {
            Taxonomy stored = getTaxonomy(taxonomy.getName());
            if (stored == null) {
                taxonomies.add(taxonomy);
                sort();
            } else {
                int idx = taxonomies.indexOf(stored);
                taxonomies.set(idx, taxonomy);
            }
            taxonomyPersistence.writeTaxonomy(taxonomy.getName(), taxonomy, null);
        }
    }

    @Override
    public void saveTaxonomy(@NotNull String taxonomy, @NotNull Taxonomy taxonomyObj)
            throws NoSuchTaxonomyException {
        synchronized (this) {
            if (!hasTaxonomy(taxonomy))
                throw new NoSuchTaxonomyException(taxonomy);
            taxonomies.remove(getTaxonomy(taxonomy));
            taxonomies.add(taxonomyObj);
            sort();
            taxonomyPersistence.writeTaxonomy(taxonomy, taxonomyObj, null);
        }
    }

    @Override
    public void deleteTaxonomy(@NotNull String name) {
        synchronized (this) {
            Taxonomy taxonomy = getTaxonomy(name);
            if (taxonomy != null) {
                taxonomyPersistence.removeTaxonomy(name, null);
                taxonomies.remove(taxonomy);
            }
        }
    }

    @Override
    public Iterable<Vocabulary> getVocabularies(@NotNull String name) {
        Taxonomy taxonomy = getTaxonomy(name);
        if (taxonomy == null)
            throw new NoSuchTaxonomyException(name);
        return taxonomy.getVocabularies();
    }

    @Override
    public boolean hasVocabulary(@NotNull String taxonomyName, @NotNull String vocabularyName)
            throws NoSuchTaxonomyException {
        Taxonomy taxonomy = getTaxonomy(taxonomyName);
        if (taxonomy == null)
            throw new NoSuchTaxonomyException(taxonomyName);
        return taxonomy.hasVocabulary(vocabularyName);
    }

    @Override
    public Vocabulary getVocabulary(@NotNull String taxonomyName, @NotNull String vocabularyName) {
        Taxonomy taxonomy = getTaxonomy(taxonomyName);
        if (taxonomy == null)
            throw new NoSuchTaxonomyException(taxonomyName);
        return taxonomy.getVocabulary(vocabularyName);
    }

    @Override
    public void saveVocabulary(@Nullable String taxonomyName, @NotNull Vocabulary vocabulary) {
        Taxonomy taxonomy = getTaxonomy(taxonomyName);
        if (taxonomy == null)
            throw new NoSuchTaxonomyException(taxonomyName);
        taxonomy.addVocabulary(vocabulary);
        saveTaxonomy(taxonomy);
    }

    @Override
    public void saveVocabulary(@NotNull String taxonomyName, @NotNull String vocabularyName,
            @NotNull Vocabulary vocabulary) throws NoSuchTaxonomyException, NoSuchVocabularyException {
        Taxonomy taxonomy = getTaxonomy(taxonomyName);
        if (taxonomy == null)
            throw new NoSuchTaxonomyException(taxonomyName);
        taxonomy.updateVocabulary(vocabularyName, vocabulary);
        saveTaxonomy(taxonomy);
    }

    @Override
    public void deleteVocabulary(@Nullable String taxonomyName, @NotNull String vocabularyName) {
        Taxonomy taxonomy = getTaxonomy(taxonomyName);
        if (taxonomy == null)
            throw new NoSuchTaxonomyException(taxonomyName);
        taxonomy.removeVocabulary(vocabularyName);
        saveTaxonomy(taxonomy);
    }

    //
    // Private methods
    //

    private void sort() {
        Collections.sort(taxonomies, new Comparator<Taxonomy>() {

            @Override
            public int compare(Taxonomy t1, Taxonomy t2) {
                return t1.getName().compareTo(t2.getName());
            }

        });
    }

    private void importDefault(boolean override) {
        if (taxonomyReferences == null || taxonomyReferences.trim().isEmpty())
            return;

        for (String uri : taxonomyReferences.split(",")) {
            importUriTaxonomy(uri.trim(), override);
        }
    }

    private Taxonomy importGitHubTaxonomy(@NotNull String username, @NotNull String repo, @Nullable String ref,
            @NotNull String taxonomyFile, boolean override) {
        String user = username;
        if (Strings.isNullOrEmpty(username))
            user = MLSTRM_USER;
        if (Strings.isNullOrEmpty(repo))
            throw new IllegalArgumentException("GitHub repository is required");
        String reference = ref;
        if (Strings.isNullOrEmpty(ref))
            reference = "master";
        String fileName = taxonomyFile;
        if (Strings.isNullOrEmpty(taxonomyFile))
            fileName = TAXONOMY_YAML;
        if (!fileName.endsWith(".yml"))
            fileName = taxonomyFile + "/" + TAXONOMY_YAML;

        String uri = GITHUB_URL + "/" + user + "/" + repo + "/" + reference + "/" + fileName;

        return importUriTaxonomy(uri, override);
    }

    private Taxonomy importUriTaxonomy(@NotNull String uri, boolean override) {
        try {
            InputStream input = new URL(uri).openStream();
            TaxonomyYaml yaml = new TaxonomyYaml();
            Taxonomy taxonomy = yaml.load(input);
            if (override || !hasTaxonomy(taxonomy.getName())) {
                saveTaxonomy(taxonomy);
                return taxonomy;
            }
        } catch (Exception e) {
            log.error("Failed loading taxonomy from: " + uri, e);
        }
        return null;
    }

    private FileObject resolveFileInFileSystem(String path) throws FileSystemException {
        return opalRuntime.getFileSystem().getRoot().resolveFile(path);
    }

    /**
     * For testing.
     */
    void clear() {
        taxonomies.clear();
    }

}