it.tidalwave.bluebill.mobile.taxonomy.TaxonomyPreferencesSupport Maven / Gradle / Ivy
/***********************************************************************************************************************
*
* blueBill Mobile - open source birdwatching
* ==========================================
*
* Copyright (C) 2009, 2010 by Tidalwave s.a.s. (http://www.tidalwave.it)
* http://bluebill.tidalwave.it/mobile/
*
***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************
*
* $Id: TaxonomyPreferencesSupport.java,v 1730f20cfb54 2010/06/26 22:26:06 fabrizio $
*
**********************************************************************************************************************/
package it.tidalwave.bluebill.mobile.taxonomy;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
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.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import it.tidalwave.util.NotFoundException;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.netbeans.util.Locator;
import it.tidalwave.bluebill.taxonomy.Taxon;
import it.tidalwave.bluebill.taxonomy.Taxonomy;
import it.tidalwave.bluebill.taxonomy.Taxonomy.Type;
import it.tidalwave.bluebill.taxonomy.TaxonomyFactory;
import it.tidalwave.mobile.preferences.PreferencesAdapter;
import java.util.Collection;
/***********************************************************************************************************************
*
* @author Fabrizio Giudici
* @version $Id: $
*
**********************************************************************************************************************/
public abstract class TaxonomyPreferencesSupport implements TaxonomyPreferences
{
private static final String CLASS = TaxonomyPreferencesSupport.class.getName();
private static final Logger logger = Logger.getLogger(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";
private static final String DEFAULT_NAME_MATCHER = "FastNameMatcherWithInitial";
@CheckForNull
protected Taxonomy taxonomy;
protected final List taxonLocales = new ArrayList();
protected Locale primaryTaxonLocale = Locale.ENGLISH;
protected NameMatcher nameMatcher;
protected Collator taxonCollator = Collator.getInstance();
protected final Map matcherMapByKey = new HashMap();
protected final PreferencesAdapter preferencesAdapter = Locator.find(PreferencesAdapter.class);
public int taxonomyLoadCount = 0;
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
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)
{
return "ZZZZZZZZZ"; // so it's sorted at last
}
}
};
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
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 NameMatcher getNameMatcher()
{
return nameMatcher;
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public Comparator getTaxonComparator()
{
return taxonComparator;
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public synchronized Taxonomy getTaxonomy()
{
if (taxonomy == null)
{
try
{
taxonomyLoadCount++;
taxonomy = loadTaxonomy();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
return taxonomy;
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public List getTaxonomyLocales()
{
return Collections.unmodifiableList(taxonLocales);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public CharSequence format (final @Nonnull Taxon taxon)
{
return format(taxon, "");
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public CharSequence format (final @Nonnull Taxon taxon, final @Nonnull String extra)
{
final StringBuilder buffer = new StringBuilder();
String separator = "";
for (final Locale locale : taxonLocales)
{
try
{
buffer.append(separator).append(taxon.getDisplayName(locale));
separator = ", ";
}
catch (NotFoundException e)
{
// don't use it
}
}
if (isScientificNamesRenderingEnabled())
{
buffer.append(" ");
if (taxon.getType() == Type.SPECIES)
{
try
{
buffer.append(String.format("(%s %s)", taxon.getParent().getScientificName(),
taxon.getScientificName()));
}
catch (NotFoundException e)
{
// never happens for SPECIES
}
}
else
{
buffer.append(String.format("(%s)", taxon.getScientificName()));
}
}
buffer.append(extra);
return buffer.toString();
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public CharSequence formatAsHtml (final @Nonnull Taxon taxon)
{
return formatAsHtml(taxon, "");
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public CharSequence formatAsHtml (final @Nonnull Taxon taxon, @Nonnull String extra)
{
return formatAsHtml(taxon, taxonLocales, isScientificNamesRenderingEnabled(), extra);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
public CharSequence formatAsHtmlSingleLanguageAndScientific (final @Nonnull Taxon taxon, @Nonnull String extra)
{
return formatAsHtml(taxon, Collections.singletonList(taxonLocales.get(0)), true, extra);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
private CharSequence formatAsHtml (final @Nonnull Taxon taxon,
final @Nonnull Collection locales,
final boolean scientificNamesRendered,
@Nonnull String extra)
{
final StringBuilder buffer = new StringBuilder();
String separator = "";
String style1 = "";
String style2 = "";
String size1 = "";
String size2 = "";
boolean atLeastOneDisplayName = false;
for (final Locale locale : locales)
{
try
{
final String displayName = taxon.getDisplayName(locale);
buffer.append(separator + size1 + style1 + displayName + extra + style2 + size2);
style1 = style2 = extra = "";
separator = "
";
size1 = "";
size2 = "";
atLeastOneDisplayName = true;
}
catch (NotFoundException e)
{
}
}
if (!atLeastOneDisplayName || scientificNamesRendered)
{
buffer.append(separator);
if (taxon.getType() == Type.SPECIES)
{
try
{
buffer.append(String.format("%s %s",
taxon.getParent().getScientificName(),
taxon.getScientificName()));
}
catch (NotFoundException e)
{
// never happens for SPECIES
}
}
else
{
buffer.append(String.format("%s", taxon.getScientificName()));
}
}
return buffer.toString();
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public boolean isScientificNamesRenderingEnabled()
{
return preferencesAdapter.getBoolean(PREF_RENDER_SCIENTIFIC_NAMES, true);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
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
{
logger.info("loadTaxonomy(%s, %s)", is, charSet);
Reader r = null;
try
{
final long time = System.currentTimeMillis();
final TaxonomyFactory taxonomyFactory = new TaxonomyFactory();
r = new InputStreamReader(is, charSet);
final Taxonomy taxonomy = taxonomyFactory.loadTaxonomy(r);
logger.info(">>>> taxonomy loaded in %s msecs", System.currentTimeMillis() - time);
return taxonomy;
}
finally
{
try
{
if (r != null)
{
r.close();
}
}
catch (IOException e)
{
logger.info("Loading the taxonomy: %s", e);
logger.throwing("loadTaxonomy()", CLASS, e);
}
}
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
protected void computeLocales()
{
logger.info("computeLocales() - default is %s", 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);
}
logger.info(">>>> locales: %s, primary: %s", taxonLocales, primaryTaxonLocale);
taxonCollator = Collator.getInstance(primaryTaxonLocale);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
@Nonnull
protected Locale getLocale (final @Nonnull String key, final @Nonnull Locale defaultLocale)
{
final String localeCode = preferencesAdapter.getString(key, "");
return localeCode.equals("") ? defaultLocale : new Locale(localeCode);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
protected void setNameMatcher()
{
final String key = preferencesAdapter.getString(PREF_NAME_MATCHER, DEFAULT_NAME_MATCHER);
nameMatcher = matcherMapByKey.get(key);
if (nameMatcher == null) // defensive
{
logger.warning("Cannot set name matcher %s - available: %s - using a default", key, matcherMapByKey.keySet());
nameMatcher = new FastNameMatcher(true);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy