package org.unicode.cldr.draft; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import com.ibm.icu.text.Transform; public class EnumLookup> { private final String name; private final Map map = new HashMap(); private Transform transform; public static > EnumLookup of(Class className) { return of(className, null, null); } @SuppressWarnings("unchecked") public static > EnumLookup of(Class className, Transform t, String from, T to, Object... extras) { Map newExtras = new HashMap(); newExtras.put(from, to); for (int i = 0; i < extras.length; i += 2) { newExtras.put(extras[i].toString(), (T) extras[i + 1]); } return of(className, t, newExtras); } public static > EnumLookup of(Class className, Transform t, Map extras) { String name_ = className.getName(); int lastDot = name_.lastIndexOf('.'); EnumLookup result = new EnumLookup(name_.substring(lastDot + 1)); try { result.transform = t = t == null ? CLEAN : t; Method m = className.getMethod("values", (Class[]) null); @SuppressWarnings("unchecked") T[] values = (T[]) m.invoke(null); for (T value : values) { result.map.put(t.transform(value.name()), value); result.map.put(t.transform(value.toString()), value); } } catch (Exception e) { throw new IllegalArgumentException(e); } if (extras == null) { return result; } for (Entry entry : extras.entrySet()) { final String key = t.transform(entry.getKey()); final T newValue = entry.getValue(); final T old = result.map.get(key); if (old == null) { result.map.put(key, newValue); } else if (old != newValue) { throw new IllegalArgumentException("Incompatible mapping: " + key + "=" + old + "!=" + newValue); } } return result; } private static Transform CLEAN = new Transform() { @Override public String transform(String in) { return in.toUpperCase(Locale.ENGLISH).replace(' ', '_'); } }; public T forString(String s) { return forString(s, false); } public T forString(String s, boolean allowNull) { T result = map.get(transform.transform(s)); if (!allowNull && result == null) { throw new IllegalArgumentException("Can't find match for «" + s + "» in " + map.keySet() + " in " + name); } return result; } private EnumLookup(String name) { this.name = name; } }