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

com.onegini.sdk.util.LocaleCodeUtils Maven / Gradle / Ivy

There is a newer version: 5.92.0
Show newest version
/*
 * Copyright 2013-2020 Onegini b.v.
 *
 * 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.
 */
package com.onegini.sdk.util;

import static java.util.Objects.isNull;
import static org.apache.commons.lang3.StringUtils.isAlphanumeric;

import java.util.Locale;

import org.apache.commons.lang3.StringUtils;

import com.neovisionaries.i18n.LocaleCode;

public class LocaleCodeUtils {

  private static final String DASH = "-";
  static final String UNDERSCORE = "_";

  private LocaleCodeUtils() {
  }

  /**
   * This method can return null for non standard or invalid connections of languages and countries like en_PL
   * Use getByCodeWithFallback to avoid nulls, but aware that will call Locale.forLanguageTag(String code) with all issues related to that method
   *
   * @param code code of locale
   * @return Locale by code
   * @see Locale#forLanguageTag
   */
  public static Locale getByCode(final String code) {
    final LocaleCode localeCode = LocaleCode.getByCodeIgnoreCase(code);
    if (isNull(localeCode)) {
      final String[] localeData = getLocaleDataWithVariant(code);
      if (localeData.length != 3) {
        return null;
      }
      if (isCorrectCountryAndLanguage(localeData) && isValidVariant(localeData[2])) {
        return new Locale(localeData[0], localeData[1], localeData[2]);
      }
      return null;
    }
    return localeCode.toLocale();
  }


  public static Locale getByCodeWithFallback(final String code) {
    final Locale byCode = getByCode(code);
    if (byCode == null) {
      return tryGetFromLanguageTag(code);
    }
    return byCode;
  }

  private static Locale tryGetFromLanguageTag(final String code) {
    final Locale locale = Locale.forLanguageTag(code);
    if (locale == null || StringUtils.isEmpty(locale.toString())) {
      return Locale.forLanguageTag(replaceSeparator(code));
    }
    return locale;
  }

  private static String replaceSeparator(final String code) {
    if (code == null) {
      return null;
    }
    if (code.contains(DASH)) {
      return code.replaceAll(DASH, UNDERSCORE);
    } else {
      return code.replaceAll(UNDERSCORE, DASH);
    }
  }

  private static boolean isCorrectCountryAndLanguage(final String[] localeData) {
    return LocaleCode.getByCodeIgnoreCase(localeData[0], localeData[1]) != null;
  }

  private static String[] getLocaleDataWithVariant(final String code) {
    if (code == null) {
      return new String[0];
    }
    if (code.contains(DASH)) {
      return code.split(DASH);
    } else {
      return code.split(UNDERSCORE);
    }
  }

  /*
   * Locale.toLanguageTag() does not round trip with Locale.forLanguageTag() for custom variants
   * As we use custom variant passed in from extension as string we need to be sure we resolve locale with variants to expected strings
   * */
  public static String toCodeWithVariant(final Locale locale) {
    final StringBuilder builder = new StringBuilder(locale.getLanguage());
    if (StringUtils.isNotBlank(locale.getCountry()) || StringUtils.isNotBlank(locale.getVariant())) {
      builder.append(DASH);
    }
    if (StringUtils.isNotBlank(locale.getCountry())) {
      builder.append(locale.getCountry());
    }
    if (StringUtils.isNotBlank(locale.getVariant())) {
      builder.append(DASH).append(locale.getVariant());
    }
    return builder.toString();
  }

  // copied from removed class sun.util.locale.LanguageTag in java 11
  public static boolean isValidVariant(final String s) {
    // variant       = 5*8alphanum         ; registered variants
    //               / (DIGIT 3alphanum)
    final int len = s.length();
    if (len >= 5 && len <= 8) {
      return isAlphanumeric(s);
    }
    if (len == 4) {
      return StringUtils.isNumeric(s.substring(0, 1))
          && isAlphanumeric(s.substring(1));
    }
    return false;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy