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

com.squarespace.cldr.BundleMatcher Maven / Gradle / Ivy

package com.squarespace.cldr;

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


/**
 * Given a MetaLocale, the bundle matching attempts to find the best match
 * amongst those available in the application. For example, "sr-Cyrl-XY"
 * may be a valid locale but no bundle is available. A fallback process would
 * match the bundle that best approximates "sr-Cyrl-XY" from those available.
 * 
 * Attempts to match the logic used by Globalize to implement Language Matching.
 * See:
 *  https://github.com/rxaviers/cldrjs/blob/master/doc/bundle_lookup_matcher.md#implementation-details
 *  http://www.unicode.org/reports/tr35/#LanguageMatching
 */
class BundleMatcher {

  private final LanguageMatcher languageMatcher;
  private final Map availableBundlesMap = new HashMap<>();
  
  public BundleMatcher(LanguageMatcher languageMatcher, List availableBundles) {
    this.languageMatcher = languageMatcher;
    buildMap(availableBundles);
  }

  /**
   * Given a language tag, parse it and return the best available CLDR bundle identifier.
   */
  public CLDR.Locale match(String languageTag) {
    return match(MetaLocale.fromLanguageTag(languageTag));
  }

  /**
   * Given a Java Locale object, return the best available CLDR bundle identifier.
   */
  public CLDR.Locale match(java.util.Locale locale) {
    return match(MetaLocale.fromJavaLocale(locale));
  }

  /**
   * Given a MetaLocale object (internal to CLDR), return the best available
   * CLDR bundle identifier.
   * 
   * TODO: use language matching instead of truncation
   */
  public CLDR.Locale match(MetaLocale locale) {
    MetaLocale maxBundleId = languageMatcher.addLikelySubtags(locale);
    MetaLocale minBundleId = languageMatcher.removeLikelySubtags(maxBundleId);
    
    MetaLocale key = minBundleId.copy();
    for (int flags : LanguageMatcher.MATCH_ORDER) {
      LanguageMatcher.set(minBundleId, key, flags);
      MetaLocale result = availableBundlesMap.get(key);
      if (result != null && result.hasLanguage()) {
        return result;
      }
    }
    return availableBundlesMap.get((MetaLocale)CLDR.Locale.en);
  }
  
  /**
   * Construct a mapping from a bundle's minimum bundle identifier to the available
   * bundle identifier.
   */
  private void buildMap(List availableLocales) {
    for (CLDR.Locale locale : availableLocales) {
      MetaLocale meta = (MetaLocale)locale;
      MetaLocale maxBundleId = languageMatcher.addLikelySubtags(meta);
      MetaLocale minBundleId = languageMatcher.removeLikelySubtags(maxBundleId);
      
      MetaLocale match = availableBundlesMap.get(minBundleId);
      if (match != null && match.count() < minBundleId.count()) {
        continue;
      }
      
      availableBundlesMap.put(minBundleId, meta);
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy