package br.com.caelum.vraptor.i18n.routes; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import javax.annotation.Priority; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Alternative; import javax.inject.Inject; import javax.interceptor.Interceptor; import br.com.caelum.vraptor.Path; import br.com.caelum.vraptor.controller.BeanClass; import br.com.caelum.vraptor.controller.HttpMethod; import br.com.caelum.vraptor.core.ReflectionProvider; import br.com.caelum.vraptor.http.route.PathAnnotationRoutesParser; import br.com.caelum.vraptor.http.route.Route; import br.com.caelum.vraptor.http.route.RouteBuilder; import br.com.caelum.vraptor.http.route.Router; @ApplicationScoped @Alternative @Priority(Interceptor.Priority.LIBRARY_BEFORE) public class I18nRoutesParser extends PathAnnotationRoutesParser { private final List<Route> routes; private final RoutesResources routesResource; private final Router router; /** * @deprecated CDI eyes only */ protected I18nRoutesParser() { this(null, null, null); } @Inject public I18nRoutesParser(Router router, RoutesResources routesResource, ReflectionProvider reflectionProvider) { super(router, reflectionProvider); this.router = router; this.routesResource = routesResource; routes = new ArrayList<>(); } @Override public List<Route> rulesFor(BeanClass controller) { routes.addAll(super.rulesFor(controller)); return routes; } @Override protected String[] getURIsFor(Method javaMethod, Class<?> type) { String[] urIsFor = super.getURIsFor(javaMethod, type); for (int i = 0; i < urIsFor.length; i++) { for (ResourceBundle bundle : routesResource.getAvailableBundles()) { if(bundle.containsKey(urIsFor[i])) { Route translatedRouteWithLocalePrefix = buildWithLocalePrefix(javaMethod, type, bundle.getString(urIsFor[i]), bundle.getLocale()); routes.add(translatedRouteWithLocalePrefix); } } Route defaultRouteWithLocalePrefix = buildWithLocalePrefix(javaMethod, type, urIsFor[i], Locale.getDefault()); routes.add(defaultRouteWithLocalePrefix); } return urIsFor; } private Route buildWithLocalePrefix(Method javaMethod, Class<?> type, String uri, Locale locale) { String localePrefix = "/" + locale.getLanguage(); if(!locale.getCountry().isEmpty()) { localePrefix += "-" + locale.getCountry().toLowerCase(); } RouteBuilder rule = router.builderFor(localePrefix + uri); EnumSet<HttpMethod> methods = getHttpMethods(javaMethod); EnumSet<HttpMethod> typeMethods = getHttpMethods(type); rule.with(methods.isEmpty() ? typeMethods : methods); if(javaMethod.isAnnotationPresent(Path.class)){ rule.withPriority(javaMethod.getAnnotation(Path.class).priority()); } if (getUris(javaMethod).length > 0) { rule.withPriority(Path.DEFAULT); } rule.is(type, javaMethod); return rule.build(); } private EnumSet<HttpMethod> getHttpMethods(AnnotatedElement annotated) { EnumSet<HttpMethod> methods = EnumSet.noneOf(HttpMethod.class); for (HttpMethod method : HttpMethod.values()) { if (annotated.isAnnotationPresent(method.getAnnotation())) { methods.add(method); } } return methods; } }