-
Notifications
You must be signed in to change notification settings - Fork 677
[#2064] Multilangual routes files support #1012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.4.x
Are you sure you want to change the base?
Changes from 5 commits
53d8547
8067cc2
899fc56
8cb5410
1387458
c21cdf1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,33 +1,30 @@ | ||
| package play.mvc; | ||
|
|
||
| import java.io.File; | ||
| import java.io.IOException; | ||
| import java.io.UnsupportedEncodingException; | ||
| import java.net.URLEncoder; | ||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.concurrent.ConcurrentHashMap; | ||
| import java.util.concurrent.CopyOnWriteArrayList; | ||
|
|
||
| import org.apache.commons.lang.StringUtils; | ||
|
|
||
| import jregex.Matcher; | ||
| import jregex.Pattern; | ||
| import jregex.REFlags; | ||
| import org.apache.commons.lang.StringUtils; | ||
| import play.Logger; | ||
| import play.Play; | ||
| import play.Play.Mode; | ||
| import play.exceptions.NoRouteFoundException; | ||
| import play.i18n.Lang; | ||
| import play.mvc.results.NotFound; | ||
| import play.mvc.results.RenderStatic; | ||
| import play.templates.TemplateLoader; | ||
| import play.utils.Default; | ||
| import play.utils.Utils; | ||
| import play.vfs.VirtualFile; | ||
|
|
||
| import java.io.File; | ||
| import java.io.IOException; | ||
| import java.io.UnsupportedEncodingException; | ||
| import java.net.URLEncoder; | ||
| import java.nio.file.Paths; | ||
| import java.util.*; | ||
| import java.util.concurrent.ConcurrentHashMap; | ||
| import java.util.concurrent.CopyOnWriteArrayList; | ||
|
|
||
| /** | ||
| * The router matches HTTP requests to action invocations | ||
| */ | ||
|
|
@@ -54,7 +51,9 @@ public class Router { | |
| public static void load(String prefix) { | ||
| routes.clear(); | ||
| actionRoutesCache.clear(); | ||
| parse(Play.routes, prefix); | ||
| for (VirtualFile routeFile : Play.routes) { | ||
| parse(routeFile, prefix); | ||
| } | ||
| lastLoading = System.currentTimeMillis(); | ||
| // Plugins | ||
| Play.pluginCollection.onRoutesLoaded(); | ||
|
|
@@ -140,6 +139,7 @@ public static Route getRoute(String method, String path, String action, String p | |
| route.routesFileLine = line; | ||
| route.addFormat(headers); | ||
| route.addParams(params); | ||
| route.setLocaleBasedOnMultilangualRoutesFile(sourceFile); | ||
| route.compute(); | ||
| if (Logger.isTraceEnabled()) { | ||
| Logger.trace("Adding [" + route.toString() + "] with params [" + params + "] and headers [" + headers + "]"); | ||
|
|
@@ -227,14 +227,16 @@ public static void detectChanges(String prefix) { | |
| if (Play.mode == Mode.PROD && lastLoading > 0) { | ||
| return; | ||
| } | ||
| if (Play.routes.lastModified() > lastLoading) { | ||
| load(prefix); | ||
| } else { | ||
| for (VirtualFile file : Play.modulesRoutes.values()) { | ||
| if (file.lastModified() > lastLoading) { | ||
| load(prefix); | ||
| return; | ||
| } | ||
| for (VirtualFile route : Play.routes) { | ||
| if (route.lastModified() > lastLoading) { | ||
| load(prefix); | ||
| return; | ||
| } | ||
| } | ||
| for (VirtualFile file : Play.modulesRoutes.values()) { | ||
| if (file.lastModified() > lastLoading) { | ||
| load(prefix); | ||
| return; | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -292,6 +294,9 @@ public static Route route(Http.Request request) { | |
| if (request.action.equals("404")) { | ||
| throw new NotFound(route.path); | ||
| } | ||
| if(Play.multilangRouteFiles && StringUtils.isNotEmpty(route.locale) && !route.locale.equals(Lang.get())){ | ||
| Lang.change(route.locale); | ||
| } | ||
| return route; | ||
| } | ||
| } | ||
|
|
@@ -588,6 +593,9 @@ private static List<ActionRoute> getActionRoutes(String action) { | |
| matchingRoutes = findActionRoutes(action); | ||
| actionRoutesCache.put(action, matchingRoutes); | ||
| } | ||
| if(Play.multilangRouteFiles){ | ||
| prioritizeActionRoutesBasedOnActiveLocale(matchingRoutes); | ||
| } | ||
| return matchingRoutes; | ||
| } | ||
|
|
||
|
|
@@ -614,6 +622,26 @@ private static List<ActionRoute> findActionRoutes(String action) { | |
| return matchingRoutes; | ||
| } | ||
|
|
||
| /** | ||
| * Prioritize action routes based on active locale and Play.langs properties. Active lang has highest priority, then prioritized according to Play.langs order. | ||
| * | ||
| * @param matchingRoutes | ||
| */ | ||
| private static void prioritizeActionRoutesBasedOnActiveLocale(List<Router.ActionRoute> matchingRoutes) { | ||
| if(matchingRoutes.size()==0) return; | ||
| final String locale = Lang.get(); | ||
| if(StringUtils.isEmpty(locale)) return; | ||
| matchingRoutes.sort(new Comparator<ActionRoute>() { | ||
|
||
| @Override | ||
| public int compare(ActionRoute ar1, ActionRoute ar2) { | ||
| if(locale.equals(ar1.route.locale)) return -1; | ||
| if(locale.equals(ar2.route.locale)) return 1; | ||
| return Integer.compare(Play.langs.indexOf(ar1.route.locale), Play.langs.indexOf(ar2.route.locale)); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
|
|
||
| private static final class ActionRoute { | ||
| private Route route; | ||
| private Map<String, String> args = new HashMap<>(2); | ||
|
|
@@ -732,6 +760,7 @@ public static class Route { | |
| static Pattern customRegexPattern = new Pattern("\\{([a-zA-Z_][a-zA-Z_0-9]*)\\}"); | ||
| static Pattern argsPattern = new Pattern("\\{<([^>]+)>([a-zA-Z_0-9]+)\\}"); | ||
| static Pattern paramPattern = new Pattern("([a-zA-Z_0-9]+):'(.*)'"); | ||
| String locale; | ||
|
|
||
| public void compute() { | ||
| this.host = ""; | ||
|
|
@@ -975,5 +1004,15 @@ static class Arg { | |
| public String toString() { | ||
| return method + " " + path + " -> " + action; | ||
| } | ||
|
|
||
| private void setLocaleBasedOnMultilangualRoutesFile(String absolutePath){ | ||
| if(StringUtils.isEmpty(absolutePath)){ | ||
| return; | ||
| } | ||
| String fileName = Paths.get(absolutePath).getFileName().toString(); | ||
| if(StringUtils.isNotEmpty(fileName) && fileName.matches("routes\\.[A-Za-z]{2}(_[A-Za-z]{2})?")){ | ||
| this.locale = fileName.split("\\.")[1]; | ||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It breaks backward compatibility.
I suggest leaving
VirtualFile routesuntouched and adding a new fieldList<VirtualFile> internationalizedRoutes. In this case you don't need fieldmultilangRouteFiles.