package com.googlecode.gwt.test.internal.i18n;
import com.google.gwt.i18n.client.*;
import com.google.gwt.i18n.client.impl.CldrImpl;
import com.google.gwt.i18n.client.impl.cldr.DateTimeFormatInfoImpl;
import com.googlecode.gwt.test.GwtCreateHandler;
import com.googlecode.gwt.test.exceptions.GwtTestI18NException;
import com.googlecode.gwt.test.internal.GwtConfig;
import com.googlecode.gwt.test.utils.GwtReflectionUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* Class in charge of the instanciation of all {@link LocalizableResource} sub-interfaces through
* deferred binding. <strong>For internal use only.</strong>
*
* @author Gael Lazzari
*/
public class LocalizableResourceCreateHandler implements GwtCreateHandler {
private static class LocalizableResourceProxyFactory {
private static Map<String, LocalizableResourceProxyFactory> factoryMap = new HashMap<String, LocalizableResourceProxyFactory>();
public static <T extends LocalizableResource> LocalizableResourceProxyFactory getFactory(
Class<T> clazz) {
LocalizableResourceProxyFactory factory = factoryMap.get(clazz.getName());
if (factory == null) {
factory = new LocalizableResourceProxyFactory(clazz);
factoryMap.put(clazz.getName(), factory);
}
return factory;
}
private final Class<? extends LocalizableResource> proxiedClass;
private LocalizableResourceProxyFactory(Class<? extends LocalizableResource> proxiedClass) {
this.proxiedClass = proxiedClass;
}
@SuppressWarnings("unchecked")
public <T extends LocalizableResource> T createProxy() {
InvocationHandler ih = createInvocationHandler(proxiedClass);
return (T) Proxy.newProxyInstance(proxiedClass.getClassLoader(),
new Class<?>[]{proxiedClass}, ih);
}
private InvocationHandler createInvocationHandler(Class<? extends LocalizableResource> clazz) {
if (ConstantsWithLookup.class.isAssignableFrom(clazz)) {
return new ConstantsWithLookupInvocationHandler(clazz);
}
if (Constants.class.isAssignableFrom(clazz)) {
return new ConstantsInvocationHandler(clazz);
} else if (Messages.class.isAssignableFrom(clazz)) {
return new MessagesInvocationHandler(clazz);
} else {
throw new GwtTestI18NException("Not managed GWT i18n interface for testing : "
+ clazz.getSimpleName());
}
}
}
@SuppressWarnings("unchecked")
public Object create(Class<?> classLiteral) throws Exception {
if (LocalizableResource.class.isAssignableFrom(classLiteral)) {
if (!classLiteral.isInterface()) {
throw new GwtTestI18NException(classLiteral.getSimpleName() + " must be an interface");
}
return LocalizableResourceProxyFactory.getFactory(
(Class<? extends LocalizableResource>) classLiteral).createProxy();
} else if (CldrImpl.class == classLiteral) {
return getLocalizedClassImpl(CldrImpl.class, CldrImpl.class);
} else if (DateTimeFormatInfoImpl.class == classLiteral) {
return getLocalizedClassImpl(DateTimeFormatInfoImpl.class, DefaultDateTimeFormatInfo.class);
}
return null;
}
private Object getLocalizedClassImpl(Class<?> localizedClass, Class<?> defaultImpl)
throws Exception {
Locale locale = GwtConfig.get().getModuleRunner().getLocale();
if (locale == null) {
return defaultImpl.newInstance();
}
Class<?> implementationClass = getLocalizedClassImpl(localizedClass, locale.getLanguage() + "_" + locale.getCountry());
if (implementationClass == null) {
implementationClass = getLocalizedClassImpl(localizedClass, locale.getLanguage());
}
if (implementationClass == null) {
implementationClass = getLocalizedClassImpl(localizedClass, locale.getCountry());
}
if (implementationClass == null) {
implementationClass = defaultImpl;
}
return implementationClass.newInstance();
}
private Class<?> getLocalizedClassImpl(Class<?> localizedClass, String suffix) {
try {
return GwtReflectionUtils.getClass(localizedClass.getName() + "_" + suffix);
} catch (ClassNotFoundException e) {
return null;
}
}
}