All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.tidalwave.bluebill.taxonomy.elmo.impl.ElmoTaxon Maven / Gradle / Ivy

/***********************************************************************************************************************
 *
 * blueBill Core - open source birding
 * Copyright (C) 2009-2011 by Tidalwave s.a.s. (http://www.tidalwave.it)
 *
 ***********************************************************************************************************************
 *
 * 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.
 *
 ***********************************************************************************************************************
 *
 * WWW: http://bluebill.tidalwave.it
 * SCM: https://kenai.com/hg/bluebill~core-src
 *
 **********************************************************************************************************************/
package it.tidalwave.bluebill.taxonomy.elmo.impl;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.xml.namespace.QName;
import it.tidalwave.util.Id;
import it.tidalwave.util.Initializer;
import it.tidalwave.util.NotFoundException;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.openrdf.elmo.RDFUtils;
import it.tidalwave.bluebill.taxonomy.Finder;
import it.tidalwave.bluebill.taxonomy.Taxonomy;
import it.tidalwave.bluebill.taxonomy.Taxon;
import it.tidalwave.bluebill.taxonomy.elmo.ElmoTaxonomyVocabulary;
import static it.tidalwave.bluebill.taxonomy.elmo.ElmoTaxonomyVocabulary.*;
import it.tidalwave.openrdf.elmo.ElmoManagerThreadLocal;
import it.tidalwave.role.LocalizedDisplayable;
import java.util.EnumMap;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;
import org.openrdf.model.Literal;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.elmo.annotations.rdf;
import org.openrdf.elmo.Entity;
import org.openrdf.elmo.ResourceManager;
import org.openrdf.elmo.sesame.SesameManager;
import org.openrdf.concepts.skos.core.Concept;
import org.openrdf.concepts.skos.core.ConceptScheme;

/***********************************************************************************************************************
 *
 * @author  Fabrizio Giudici
 * @version $Id$
 *
 **********************************************************************************************************************/
@rdf(ElmoTaxonomyVocabulary.URI_TAXON)
public class ElmoTaxon extends Support implements InternalElmoTaxon
  {
    private static final String CLASS = ElmoTaxon.class.getName();
    private static final Logger logger = Logger.getLogger(CLASS);
    
    @Nonnull
    private Repository repository;

    @Nonnull
    private Taxonomy taxonomy;

//    @rdf(ElmoTaxonomyVocabulary.URI_SCIENTIFIC_NAME_ID)
    @CheckForNull
    private String scientificNameId;

//    @rdf(ElmoTaxonomyVocabulary.URI_SCIENTIFIC_NAME)
    private String scientificName;

//    @rdf(ElmoTaxonomyVocabulary.URI_SPECIFIC_EPITHET)
    private String specificEpithet;

//    @rdf(ElmoTaxonomyVocabulary.URI_TAXON_RANK)
    private String rankAsString;

    private LocalizedDisplayable displayable;

    private final static Map RANK_MAP = new EnumMap(Rank.class);

    static
      {
        RANK_MAP.put(Rank.CLASS,       ID_TAXON_RANK_CLASS);
        RANK_MAP.put(Rank.ORDER,       ID_TAXON_RANK_ORDER);
        RANK_MAP.put(Rank.FAMILY,      ID_TAXON_RANK_FAMILY);
        RANK_MAP.put(Rank.SUBFAMILY,   ID_TAXON_RANK_SUBFAMILY);
        RANK_MAP.put(Rank.GENUS,       ID_TAXON_RANK_GENUS);
        RANK_MAP.put(Rank.SPECIES,     ID_TAXON_RANK_SPECIES);
        RANK_MAP.put(Rank.SUBSPECIES,  ID_TAXON_RANK_SUBSPECIES);
      }

    /*******************************************************************************************************************
     *
     *
     *
     ******************************************************************************************************************/
    public ElmoTaxon (final @Nonnull Entity entity)
      {
        super(entity);
      }

    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    public String getScientificName()
      {
        return scientificName;
      }

    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    public String getSpecificEpithet()
      {
        return specificEpithet;
      }

    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    @Nonnull @Override
    public Taxon.Builder createSubTaxon()
      {
        return taxonomy.createTaxon().withInitializer(new Initializer() 
          {
            public Taxon initialize (final @Nonnull Taxon taxon)
              {
                getLookup().lookup(Concept.class).getSkosNarrowers().add(taxon.getLookup().lookup(Concept.class));
//                as(Concept.class).getSkosNarrowers().add(taxon.as(Concept.class)); FIXME

                return taxon;
              }
          });
      }
    
    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    @Nonnull
    @Override
    public Finder findSubTaxa()
      {
        try
          {
            logger.finest("findSubConcepts() - %s", getDisplayName());

            final List result = new ArrayList();

            for (final Concept skosConcept : as(Concept.class).getSkosNarrowers())
              {
                final QName id = skosConcept.getQName();
                final InternalElmoTaxon concept = ((ElmoTaxonomy)taxonomy).conceptFactory.find(id);
                concept.setBindings(repository, taxonomy);
                result.add(concept);
              }

            return new YYYFinder(result);
          }
        catch (NotFoundException e)
          {
            throw new RuntimeException(e);
          }
      }

    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    @Override @Nonnull
    public Id getScientificNameId()
      throws NotFoundException
      {
        try // FIXME: workaround because the @rdf annotation of this.synonym doesn't work
          {
            final SesameManager em = (SesameManager)ElmoManagerThreadLocal.get();
            final ResourceManager rm = em.getResourceManager();
            final RepositoryResult triples = em.getConnection().getStatements(rm.createResource(getLookup().lookup(Entity.class).getQName()),
                                                                                         new URIImpl(ElmoTaxonomyVocabulary.URI_SCIENTIFIC_NAME_ID),
                                                                                         null);
            if (!triples.hasNext())
              {
                throw new NotFoundException("scientificNameId");
              }

            final Statement triple = triples.next();
            final Literal uri = (Literal)triple.getObject();
            return new Id(uri.stringValue());
          }
        catch (RepositoryException e)
          {
            throw new RuntimeException(e);
          }
      }

    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    @Override
    public Taxon getAnonymousSynonym()
//    public AnonymousTaxon getAnonymousSynonym()
      throws NotFoundException
      {
        try // FIXME: workaround because the @rdf annotation of this.synonym doesn't work
          {
            final SesameManager em = (SesameManager)ElmoManagerThreadLocal.get();
            final ResourceManager rm = em.getResourceManager();
            final RepositoryResult triples = em.getConnection().getStatements(rm.createResource(getLookup().lookup(Entity.class).getQName()),
                                                                                         new URIImpl(ElmoTaxonomyVocabulary.URI_SCIENTIFIC_NAME_ID),
                                                                                         null);
            if (!triples.hasNext())
              {
                throw new NotFoundException("No synonyms");
              }

            final Statement triple = triples.next();
            final Literal uri = (Literal)triple.getObject();
            return taxonomy.findOrCreateAnonymousTaxon(uri.stringValue());
          }
        catch (RepositoryException e)
          {
            throw new RuntimeException(e);
          }
//        if (synonym == null)
//          {
//            throw new NotFoundException("No synonyms.");
//          }
//
//        return synonym;
      }


    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    @Override
    public Finder findSynonyms()
      {        
        try
          {
            final List synonyms =
                    new ArrayList(getAnonymousSynonym().findSynonyms().results());

            for (final Iterator i = synonyms.iterator(); i.hasNext(); )
              {
//                if (this.equals(i.next())) FIXME
                if (as(Entity.class).getQName().equals(i.next().as(Entity.class).getQName()))
                  {
                    i.remove();
                    break;
                  }
              }

            return new YYYFinder(synonyms);
          }
        catch (NotFoundException e)
          {
            return new YYYFinder(Collections.emptyList());
          }
      }
    
    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    @Override
    public void init (final @Nonnull Taxon.Builder builder,
                      final @Nonnull Taxonomy taxonomy)
      {
        logger.finest("init(%s, %s) - @%x", builder, taxonomy, System.identityHashCode(this));

        scientificName = builder.getScientificName();

        if (scientificName != null)
          {
            RDFUtils.setDisplayName(entity, builder.getScientificName());
          }

        displayable = builder.getDisplayable();
        setDisplayNames(as(Entity.class), displayable);

        final Concept skosConcept = as(Concept.class);
        skosConcept.getSkosInSchemes().add(taxonomy.as(ConceptScheme.class));

        if (scientificName != null)
          {
            addStatement(ElmoTaxonomyVocabulary.URI_SCIENTIFIC_NAME, scientificName); // FIXME: workaround because the @rdf annotation doesn't work
          }

        specificEpithet = builder.getSpecificEpythet();

        if (specificEpithet != null)
          {
            addStatement(ElmoTaxonomyVocabulary.URI_SPECIFIC_EPITHET, specificEpithet); // FIXME: workaround because the @rdf annotation doesn't work
          }

        final Id tmp = builder.getScientificNameId();

        if (tmp != null)
          {
            scientificNameId = tmp.stringValue();
            addStatement(ElmoTaxonomyVocabulary.URI_SCIENTIFIC_NAME_ID, scientificNameId); // FIXME: workaround because the @rdf annotation of this.scientificNameId doesn't work

    //        final Concept asConcept = synonym.getLookup().lookup(Concept.class); // FIXME: as() doesn't work
    //        asConcept.getSkosNotes().add("debugging-info: " + getLookup().lookup(Entity.class).getQName().getLocalPart()); // For debugging only FIXME: use as()
          }

        rankAsString = RANK_MAP.get(builder.getRank());

        if (rankAsString != null)
          {
            addStatement(ElmoTaxonomyVocabulary.URI_TAXON_RANK, rankAsString); // FIXME: workaround because the @rdf annotation of this.rank doesn't work
          }
      }

    /*******************************************************************************************************************
     *
     * {@inheritDoc}
     *
     ******************************************************************************************************************/
    @Override
    public void setBindings (final @Nonnull Repository repository,
                             final @Nonnull Taxonomy taxonomy)
      {
        logger.finest("setBindings(%s, %s) - @%x", repository, taxonomy, System.identityHashCode(this));
        
        this.taxonomy = taxonomy;
        this.repository = repository;
      }

    @Override @Nonnull
    public Map getDisplayNames()
      {
        throw new UnsupportedOperationException("Not supported yet.");
      }

//    private void addStatement (final @Nonnull String uri, final @Nonnull Lookup.Provider object)
//      {
//        final SesameManager em = (SesameManager)ElmoManagerThreadLocal.get();
//        final ResourceManager rm = em.getResourceManager();
//
//        try
//          {
//            em.getConnection().add(rm.createResource(getLookup().lookup(Entity.class).getQName()),
//                                   new URIImpl(uri),
//                                   rm.createResource(object.getLookup().lookup(Entity.class).getQName())); // FIXME
//          }
//        catch (RepositoryException e)
//          {
//            throw new RuntimeException(e);
//          }
//      }

    private void addStatement (final @Nonnull String uri, final @Nonnull String string)
      {
        final SesameManager em = (SesameManager)ElmoManagerThreadLocal.get();
        final ResourceManager rm = em.getResourceManager();

        try
          {
            em.getConnection().add(rm.createResource(getLookup().lookup(Entity.class).getQName()),
                                   new URIImpl(uri),
                                   em.getLiteralManager().getLiteral(string));
          }
        catch (RepositoryException e)
          {
            throw new RuntimeException(e);
          }
      }

    // FIXME: move to RDFUtils
    private static void setDisplayNames (final @Nonnull Entity entity, final @Nonnull LocalizedDisplayable displayable)
      {
        final SortedMap sortedMap = new TreeMap();

        for (final Entry entry : displayable.getDisplayNames().entrySet())
          {
            if (!entry.getValue().equals(""))
              {
                sortedMap.put(languageCode(entry.getKey()), entry.getKey());
              }
          }

        for (final Entry entry : sortedMap.entrySet())
          {
            final Locale locale = entry.getValue();
            RDFUtils.setDisplayName(entity, displayable.getDisplayName(locale), locale);
          }
      }

    @Nonnull
    private static String languageCode (final @Nonnull Locale locale)
      {
        final StringBuilder buffer = new StringBuilder(locale.getLanguage());
        final String country = locale.getCountry();

        if ((country != null) && !"".equals(country))
          {
            buffer.append("_").append(country.toUpperCase());
          }

        return buffer.toString();
      }
  }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy