Android implementation of UrlRemap.

Project: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/cordova-app-harness/commit/5ab66f57
Tree: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/tree/5ab66f57
Diff: http://git-wip-us.apache.org/repos/asf/cordova-app-harness/diff/5ab66f57

Branch: refs/heads/master
Commit: 5ab66f572d071e0ddcc67284202ad3aa9e7ab908
Parents: 06150bc
Author: Andrew Grieve <[email protected]>
Authored: Wed Oct 23 21:43:29 2013 -0400
Committer: Andrew Grieve <[email protected]>
Committed: Wed Oct 23 21:55:18 2013 -0400

----------------------------------------------------------------------
 UrlRemap/src/android/UrlRemap.java | 164 +++++++++++++-------------------
 1 file changed, 64 insertions(+), 100 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-app-harness/blob/5ab66f57/UrlRemap/src/android/UrlRemap.java
----------------------------------------------------------------------
diff --git a/UrlRemap/src/android/UrlRemap.java 
b/UrlRemap/src/android/UrlRemap.java
index deb7f12..fe49b7e 100644
--- a/UrlRemap/src/android/UrlRemap.java
+++ b/UrlRemap/src/android/UrlRemap.java
@@ -23,127 +23,94 @@ import java.util.List;
 import java.util.regex.Pattern;
 
 import org.apache.cordova.CallbackContext;
-import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaArgs;
 import org.apache.cordova.CordovaPlugin;
+import org.json.JSONException;
+
 import android.net.Uri;
-import android.net.Uri.Builder;
-import android.util.Log;
 
 public class UrlRemap extends CordovaPlugin {
-    private static final String LOG_TAG = "UrlRemap";
-    private static final String APP_BUNDLE_REPLACED = "UrlRemapReplaced";
-
     private static class RouteParams {
-        public String matchRegex;
-        public String replaceRegex;
-        public String replacer;
-        public boolean redirectToReplacedUrl;
-
-        public RouteParams(String matchRegex, String replaceRegex, String 
replacer, boolean redirectToReplacedUrl){
-            this.matchRegex = matchRegex;
-            this.replaceRegex = replaceRegex;
-            this.replacer = replacer;
-            this.redirectToReplacedUrl = redirectToReplacedUrl;
-        }
+        Pattern matchRegex;
+        Pattern replaceRegex;
+        String replacer;
+        boolean redirectToReplacedUrl;
+        String jsToInject;
     }
 
-    private final String BUNDLE_PATH = "file:///android_asset/www/";
     // Have a default replacement path that redirects app-bundle: uri's to the 
bundle
-    private final RouteParams appBundleParams = new 
RouteParams("^app-bundle:///.*", "^app-bundle:///", BUNDLE_PATH, true);
+    private RouteParams resetUrlParams;
     private List<RouteParams> rerouteParams = new ArrayList<RouteParams>();
 
     @Override
-    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
-        super.initialize(cordova, webView);
-        resetMap();
-    }
-    private void resetMap(){
-        rerouteParams.clear();
-        rerouteParams.add(appBundleParams);
-    }
-
-    @Override
-    public boolean execute(String action, CordovaArgs args, final 
CallbackContext callbackContext) {
+    public boolean execute(String action, CordovaArgs args, final 
CallbackContext callbackContext) throws JSONException {
         if ("addAlias".equals(action)) {
-            addAlias(args, callbackContext);
-            return true;
+            RouteParams params = new RouteParams();
+            params.matchRegex = Pattern.compile(args.getString(0));
+            params.replaceRegex = Pattern.compile(args.getString(1));
+            params.replacer = args.getString(2);
+            params.redirectToReplacedUrl = args.getBoolean(3);
+            rerouteParams.add(params);
         } else if ("clearAllAliases".equals(action)) {
-            clearAllAliases(args, callbackContext);
-            return true;
+            resetMappings();
+        } else if ("injectJs".equals(action)) {
+            RouteParams params = new RouteParams();
+            params.matchRegex = Pattern.compile(args.getString(0));
+            params.jsToInject = args.getString(1);
+            rerouteParams.add(params);
+        } else if ("setResetUrl".equals(action)) {
+            resetUrlParams = new RouteParams();
+            resetUrlParams.matchRegex = Pattern.compile(args.getString(0));
+        } else {
+            return false;
         }
-        return false;
+        callbackContext.success();
+        return true;
     }
 
-    private void addAlias(CordovaArgs args, CallbackContext callbackContext) {
-        try {
-            String sourceUrlMatchRegex = 
args.getString(0).replace("{BUNDLE_WWW}", getRegex(BUNDLE_PATH));
-            String sourceUrlReplaceRegex = 
args.getString(1).replace("{BUNDLE_WWW}", getRegex(BUNDLE_PATH));
-            String replaceString = args.getString(2).replace("{BUNDLE_WWW}", 
BUNDLE_PATH);
-            boolean redirectToReplacedUrl = args.getBoolean(3);
-            if(replaceString.matches(sourceUrlMatchRegex)){
-                callbackContext.error("The replaceString cannot match the 
match regex. This would lead to recursive replacements.");
-            } else {
-                rerouteParams.add(new RouteParams(sourceUrlMatchRegex, 
sourceUrlReplaceRegex, replaceString, redirectToReplacedUrl));
-                callbackContext.success();
-            }
-        } catch(Exception e) {
-            callbackContext.error("Could not add alias");
-            Log.e(LOG_TAG, "Could not add alias");
-        }
+    private void resetMappings() {
+        resetUrlParams = null;
+        rerouteParams.clear();
     }
 
-    private void clearAllAliases(CordovaArgs args, CallbackContext 
callbackContext) {
-        try {
-            resetMap();
-            callbackContext.success();
-        } catch(Exception e) {
-            callbackContext.error("Could not clear aliases");
-            Log.e(LOG_TAG, "Could not clear aliases");
+    private RouteParams getChosenParams(String url, boolean forInjection) {
+        for (RouteParams params : rerouteParams) {
+            if ((params.jsToInject != null) == forInjection && 
params.matchRegex.matcher(url).find()) {
+                return params;
+            }
         }
+        return null;
     }
+    
+    @Override
+    public boolean onOverrideUrlLoading(String url) {
+        if (resetUrlParams != null && 
resetUrlParams.matchRegex.matcher(url).find()) {
+            resetMappings();
+        }
 
-    private String getRegex(String string){
-        return Pattern.quote(string);
-    }
+        RouteParams params = getChosenParams(url, false);
+        // Check if we need to replace the url
+        if (params != null && params.redirectToReplacedUrl) {
+            String newUrl = 
params.replaceRegex.matcher(url).replaceFirst(params.replacer);
 
-    private RouteParams getChosenParams(String uri){
-        if(uri == null) {
-            return null;
-        } else {
-            uri = Uri.parse(uri).toString();
-        }
-        for(int i = rerouteParams.size() - 1; i >= 0; i--){
-            RouteParams param = rerouteParams.get(i);
-            if(uri.matches(param.matchRegex)){
-                return param;
+            if (resetUrlParams != null && 
resetUrlParams.matchRegex.matcher(newUrl).find()) {
+                resetMappings();
             }
+            
+            webView.loadUrl(newUrl);
+            return true;
         }
-        return null;
+        return false;
     }
 
     @Override
     public Object onMessage(String id, Object data) {
         // Look for top level navigation changes
-        if("onPageStarted".equals(id)){
-            String url = data == null? null: data.toString();
-            RouteParams params = getChosenParams(url);
-            // Check if we need to replace the url
-            if(params != null && params.redirectToReplacedUrl) {
-                Uri uri = Uri.parse(url);
-                // Check that the APP_BUNDLE_REPLACED query param doesn't 
exist.
-                // If it exists this means a previous app-bundle uri was 
rerouted to 'uri'. So we shouldn't reroute further.
-                if(uri.getQueryParameter(APP_BUNDLE_REPLACED) == null){
-                    String newPath = url.replaceAll(params.replaceRegex, 
params.replacer);
-                    //We need to special case app-bundle: uri's to make sure 
they aren't redirected when we load the modified url
-                    if(params.equals(appBundleParams)){
-                        // Throw in a APP_BUNDLE_REPLACED query parameter
-                        Builder builder = Uri.parse(newPath).buildUpon();
-                        builder.appendQueryParameter(APP_BUNDLE_REPLACED, 
"true");
-                        newPath = builder.build().toString();
-                    }
-                    webView.stopLoading();
-                    webView.loadUrl(newPath);
-                }
+        if ("onPageFinished".equals(id) && data != null) {
+            String url = data.toString();
+            RouteParams params = getChosenParams(url, true);
+            if (params != null) {
+                webView.sendJavascript(params.jsToInject);
             }
         }
         return null;
@@ -152,14 +119,11 @@ public class UrlRemap extends CordovaPlugin {
     @Override
     public Uri remapUri(Uri uri) {
         String uriAsString = uri.toString();
-        RouteParams params = getChosenParams(uriAsString);
-        if (params != null){
-            // Just send data as we can't tell if this is top level or not.
-            // If this is a top level request, it will get trapped in the 
onPageStarted event handled above.
-            String newUri = uriAsString.replaceAll(params.replaceRegex, 
params.replacer);
-            return webView.getResourceApi().remapUri(Uri.parse(newUri));
-        } else {
-            return uri;
+        RouteParams params = getChosenParams(uriAsString, false);
+        if (params != null && !params.redirectToReplacedUrl) {
+            String newUrl = 
params.replaceRegex.matcher(uriAsString).replaceFirst(params.replacer);
+            return Uri.parse(newUrl);
         }
+        return null;
     }
 }

Reply via email to