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

it.tidalwave.bluebill.mobile.taxonomy.spi.TaxonomyPreferencesSupport Maven / Gradle / Ivy

/***********************************************************************************************************************
 *
 * blueBill Mobile - Android - 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/mobile
 * SCM: https://java.net/hg/bluebill-mobile~android-src
 *
 **********************************************************************************************************************/
package it.tidalwave.bluebill.mobile.taxonomy.spi;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.inject.Provider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.text.Collator;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import it.tidalwave.util.NotFoundException;
import it.tidalwave.netbeans.util.Locator;
import it.tidalwave.observation.ObservationManager;
import it.tidalwave.observation.bluebill.ObservationClipboard;
import it.tidalwave.mobile.preferences.PreferencesAdapter;
import it.tidalwave.bluebill.taxonomy.mobile.Taxon;
import it.tidalwave.bluebill.taxonomy.mobile.Taxonomy;
import it.tidalwave.bluebill.taxonomy.mobile.TaxonomyFactory;
import it.tidalwave.bluebill.taxonomy.mobile.impl.SimpleTaxonomyFactory;
import it.tidalwave.bluebill.mobile.taxonomy.text.FastNameMatcher;
import it.tidalwave.bluebill.mobile.taxonomy.text.ExactSubstringNameMatcher;
import it.tidalwave.bluebill.mobile.taxonomy.text.CamelCaseMatcher;
import it.tidalwave.bluebill.mobile.taxonomy.TaxonHistory;
import it.tidalwave.bluebill.mobile.preferences.NameMatcher;
import it.tidalwave.bluebill.mobile.preferences.TaxonomyPreferences;
import lombok.Cleanup;
import lombok.Getter;

/***********************************************************************************************************************
 *
 * @author  Fabrizio Giudici
 * @version $Id$
 *
 **********************************************************************************************************************/
public abstract class TaxonomyPreferencesSupport implements TaxonomyPreferences
  {
    private static final Logger log = LoggerFactory.getLogger(TaxonomyPreferencesSupport.class);
    
    public static final String PREF_RENDER_SCIENTIFIC_NAMES = "renderScientificNames";
    public static final String PREF_PRIMARY_LOCALE = "taxonomyPrimaryLocale";
    public static final String PREF_SECONDARY_LOCALE = "taxonomySecondaryLocale";
    public static final String PREF_NAME_MATCHER = "nameMatcher/3";
    public static final String PREF_TAXONOMY = "taxonomySchema";
   
    private static final String DEFAULT_NAME_MATCHER = "FastNameMatcherWithInitial";

    @CheckForNull
    protected Taxonomy taxonomy;

    protected final List taxonLocales = new ArrayList();

    protected Locale primaryTaxonLocale = Locale.ENGLISH;

    @Getter
    protected NameMatcher nameMatcher;

    protected Collator taxonCollator = Collator.getInstance();

    protected final Map matcherMapByKey = new HashMap();

    protected final Provider preferencesAdapter = Locator.createProviderFor(PreferencesAdapter.class);

    private final Provider observationClipboard = Locator.createProviderFor(ObservationClipboard.class);
    
    private final Provider taxonHistory = Locator.createProviderFor(TaxonHistory.class);
    
    private final Provider observationManager = Locator.createProviderFor(ObservationManager.class);
        
    public int taxonomyLoadCount = 0;
    
    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Getter
    private final Comparator taxonComparator = new Comparator()
      {
        public int compare (final @Nonnull Taxon taxon1, @Nonnull final Taxon taxon2)
          {
            return taxonCollator.compare(getDisplayName(taxon1), getDisplayName(taxon2));
          }

        @Nonnull
        private String getDisplayName (final @Nonnull Taxon taxon)
          {
            try
              {
                return taxon.getDisplayName(primaryTaxonLocale);
              }
            catch (NotFoundException e)
              {
                // We prepend some zeds to scientific names, so if they are compared against common names,
                // they go to the bottom of the list.
                // FIXME: in some locales, Z is not the last letter!
                return "ZZZZZZZ" + taxon.getScientificName();
              }
          }
      };

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public TaxonomyPreferencesSupport()
      {
        matcherMapByKey.put("FastNameMatcher", new FastNameMatcher(false));
        matcherMapByKey.put("FastNameMatcherWithInitial", new FastNameMatcher(true));
        matcherMapByKey.put("CamelCaseMatcher", new CamelCaseMatcher());
        matcherMapByKey.put("ExactSubstringNameMatcher", new ExactSubstringNameMatcher());
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public String getSelectedTaxononyName()
      {
        return preferencesAdapter.get().getString(PREF_TAXONOMY, "EBNItalia2003");
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public boolean isScientificNamesRenderingEnabled()
      {
        return preferencesAdapter.get().getBoolean(PREF_RENDER_SCIENTIFIC_NAMES, true);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public synchronized Taxonomy getTaxonomy()
      {
        if (taxonomy == null)
          {
            try
              {
                taxonomyLoadCount++;
                taxonomy = loadTaxonomy();
              }
            catch (Exception e)
              {
                throw new RuntimeException(e);
              }
          }

        return taxonomy;
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public void resetTaxonomy()
      {
        log.info("resetTaxonomy()");
        taxonomy = null;
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public Taxonomy reloadTaxonomy()
      {
        log.info("reloadTaxonomy()");
        taxonomy = null;
        observationClipboard.get().clear();
        taxonHistory.get().clearTaxonHistory();
        observationManager.get().findOrCreateObservationSetById(null).clear();
        
        return getTaxonomy();
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public List getTaxonomyLocales()
      {
        return Collections.unmodifiableList(taxonLocales);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public void reset()
      {
        computeLocales();
        setNameMatcher();
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    protected abstract Taxonomy loadTaxonomy()
      throws Exception;

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    protected Taxonomy loadTaxonomy (final @Nonnull InputStream is, final @Nonnull String charSet)
      throws Exception
      {
        log.info("loadTaxonomy({}, {})", is, charSet);

        final long time = System.currentTimeMillis();
        final TaxonomyFactory taxonomyFactory = new SimpleTaxonomyFactory();
        @Cleanup final Reader r = new InputStreamReader(is, charSet);
        final Taxonomy taxonomy = taxonomyFactory.loadTaxonomy(r);
        log.info(">>>> taxonomy loaded in {} msecs", System.currentTimeMillis() - time);
        return taxonomy;
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    protected void computeLocales()
      {
        log.info("computeLocales() - default is {}", Locale.getDefault());
        primaryTaxonLocale = getLocale(PREF_PRIMARY_LOCALE, Locale.getDefault());
        final Locale secondaryTaxonLocale = getLocale(PREF_SECONDARY_LOCALE, primaryTaxonLocale);
        taxonLocales.clear();
        taxonLocales.add(primaryTaxonLocale);

        if (!primaryTaxonLocale.equals(secondaryTaxonLocale))
          {
            taxonLocales.add(secondaryTaxonLocale);
          }

        log.info(">>>> locales: {}, primary: {}", taxonLocales, primaryTaxonLocale);
        taxonCollator = Collator.getInstance(primaryTaxonLocale);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    protected Locale getLocale (final @Nonnull String key, final @Nonnull Locale defaultLocale)
      {
        final String localeCode = preferencesAdapter.get().getString(key, "");
        return localeCode.equals("") ? defaultLocale : new Locale(localeCode);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    protected void setNameMatcher()
      {
        final String key = preferencesAdapter.get().getString(PREF_NAME_MATCHER, DEFAULT_NAME_MATCHER);
        nameMatcher = matcherMapByKey.get(key);

        if (nameMatcher == null) // defensive
          {
            log.warn("Cannot set name matcher {} - available: {} - using a default", key, matcherMapByKey.keySet());
            nameMatcher = new FastNameMatcher(true);
          }
      }
  }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy