package org.commcare.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.util.LruCache;
import android.text.Spannable;
import android.util.Pair;
import org.javarosa.core.services.locale.Localization;
import org.javarosa.core.util.NoLocalizedTextException;
import java.text.Normalizer;
import java.util.regex.Pattern;
/**
* @author ctsims
*/
public class StringUtils {
//TODO: Bro you can't just cache every fucking string ever.
private static LruCache<String, String> normalizationCache;
private static Pattern diacritics;
//TODO: Really not sure about this size. Also, the LRU probably isn't really the best model here
//since we'd _like_ for these caches to get cleaned up at _some_ point.
static final private int cacheSize = 100 * 1024;
/**
* @param input A non-null string
* @return a canonical version of the passed in string that is lower cased and has removed diacritical marks
* like accents.
*/
@SuppressLint("NewApi")
public synchronized static String normalize(String input) {
if (normalizationCache == null) {
normalizationCache = new LruCache<>(cacheSize);
diacritics = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
}
String cachedString = normalizationCache.get(input);
if (cachedString != null) {
return cachedString;
}
//Initialized the normalized string (If we can, we'll use the Normalizer API on it)
String normalized = input;
//If we're above gingerbread we'll normalize this in NFD form
//which helps a lot. Otherwise we won't be able to clear up some of those
//issues, but we can at least still eliminate diacritics.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
normalized = Normalizer.normalize(input, Normalizer.Form.NFD);
} else {
//TODO: I doubt it's worth it, but in theory we could run
//some other normalization for the minority of pre-API9
//devices.
}
String output = diacritics.matcher(normalized).replaceAll("").toLowerCase();
normalizationCache.put(input, output);
return output;
}
public static String getStringRobust(Context c, int resId) {
return getStringRobust(c, resId, "");
}
public static String getStringRobust(Context c, int resId, String args) {
String resourceName = c.getResources().getResourceEntryName(resId);
try {
return Localization.get("odk_" + resourceName, new String[]{args});
} catch (NoLocalizedTextException e) {
return c.getString(resId, args);
}
}
public static String getStringRobust(Context c, int resId, @NonNull String[] args) {
String resourceName = c.getResources().getResourceEntryName(resId);
try {
return Localization.get("odk_" + resourceName, args);
} catch (NoLocalizedTextException e) {
return c.getString(resId, args);
}
}
public static Spannable getStringSpannableRobust(Context c, int resId) {
return getStringSpannableRobust(c, resId, "");
}
public static Spannable getStringSpannableRobust(Context c, int resId, String args) {
String resourceName = c.getResources().getResourceEntryName(resId);
String ret = "";
try {
ret = Localization.get("odk_" + resourceName, new String[]{args});
} catch (NoLocalizedTextException e) {
ret = c.getString(resId, args);
}
return MarkupUtil.styleSpannable(c, ret);
}
}