From 979d8e66f26d27a132d7514386b777fc8fc234f3 Mon Sep 17 00:00:00 2001 From: Andrew Grieve Date: Mon, 27 May 2013 22:22:18 -0400 Subject: [PATCH] Revert "Added "DataResource" - allows many plugins to intercept a single request" This reverts commit 62c3e4652975f3e23a2f5a203dc13f7d4c98a30e. Reverting all DataResource changes for the 2.8.0 release. Conflicts: framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java framework/src/org/apache/cordova/api/DataResource.java framework/src/org/apache/cordova/api/DataResourceContext.java --- .../src/org/apache/cordova/FileHelper.java | 58 +------ .../cordova/IceCreamCordovaWebViewClient.java | 50 ++++-- .../org/apache/cordova/api/CordovaPlugin.java | 14 -- .../org/apache/cordova/api/DataResource.java | 156 ------------------ .../cordova/api/DataResourceContext.java | 56 ------- .../org/apache/cordova/api/PluginManager.java | 26 --- 6 files changed, 36 insertions(+), 324 deletions(-) delete mode 100644 framework/src/org/apache/cordova/api/DataResource.java delete mode 100644 framework/src/org/apache/cordova/api/DataResourceContext.java diff --git a/framework/src/org/apache/cordova/FileHelper.java b/framework/src/org/apache/cordova/FileHelper.java index e7bf98a8..ebbdc8df 100644 --- a/framework/src/org/apache/cordova/FileHelper.java +++ b/framework/src/org/apache/cordova/FileHelper.java @@ -26,11 +26,10 @@ import org.apache.cordova.api.CordovaInterface; import org.apache.cordova.api.LOG; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; +import java.net.URLConnection; +import java.util.Locale; public class FileHelper { private static final String LOG_TAG = "FileUtils"; @@ -91,7 +90,7 @@ public class FileHelper { * @throws IOException */ public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova) throws IOException { - if (uriString.startsWith("content:")) { + if (uriString.startsWith("content")) { Uri uri = Uri.parse(uriString); return cordova.getActivity().getContentResolver().openInputStream(uri); } else if (uriString.startsWith("file://")) { @@ -111,57 +110,6 @@ public class FileHelper { } } - public static OutputStream getOutputStreamFromUriString(String uriString, CordovaInterface cordova) throws FileNotFoundException{ - if (uriString.startsWith("content:")) { - Uri uri = Uri.parse(uriString); - return cordova.getActivity().getContentResolver().openOutputStream(uri); - } else if (uriString.startsWith("file:") && !uriString.startsWith("file:///android_asset/")) { - String realPath = uriString.substring(7); - return new FileOutputStream(realPath); - } else { - return null; - } - } - /** - * Returns whether the uri can be written to by openeing a File to that uri - * - * @param the URI to test - * @return boolean indicating whether the uri is writable - */ - public static boolean isUriWritable(String uriString) { - String scheme = uriString.split(":")[0]; - String writableSchemes[] = new String[]{ "content" }; - - if(scheme.equals("file")){ - // special case file - if(uriString.startsWith("file:///android_asset/")){ - return false; - } else { - return true; - } - } - for(int i = writableSchemes.length - 1; i >= 0 ; i--){ - if(writableSchemes[i].equals(scheme)){ - return true; - } - } - return false; - } - - /** - * Ensures the "file://" prefix exists for the given string - * If the given URI string has a "file://" prefix, it is returned unchanged - * - * @param path - the path string to operate on - * @return a String with the "file://" scheme set - */ - public static String insertFileProtocol(String path) { - if(!path.matches("^[a-z0-9+.-]+:.*")){ - path = "file://" + path; - } - return path; - } - /** * Removes the "file://" prefix from the given URI string, if applicable. * If the given URI string doesn't have a "file://" prefix, it is returned unchanged. diff --git a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java index d71fbe86..847972ee 100644 --- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java +++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java @@ -19,10 +19,9 @@ package org.apache.cordova; import java.io.IOException; +import java.io.InputStream; import org.apache.cordova.api.CordovaInterface; -import org.apache.cordova.api.DataResource; -import org.apache.cordova.api.DataResourceContext; import org.apache.cordova.api.LOG; import android.annotation.TargetApi; @@ -44,24 +43,41 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient { @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { - // We need to support the new DataResource intercepts without breaking the shouldInterceptRequest mechanism. - DataResource dataResource = DataResource.initiateNewDataRequestForUri(url, this.appView.pluginManager, cordova, - new DataResourceContext("WebViewClient.shouldInterceptRequest", true /* this is from a browser request*/)); - url = dataResource.getUri().toString(); - //Check if plugins intercept the request WebResourceResponse ret = super.shouldInterceptRequest(view, url); -// The below bugfix is taken care of by the dataResource mechanism -// if(ret == null && (url.contains("?") || url.contains("#") || needsIceCreamSpaceInAssetUrlFix(url))){ -// ret = generateWebResourceResponse(url); -// } - if(ret == null) { - try { - ret = new WebResourceResponse(dataResource.getMimeType(), "UTF-8", dataResource.getInputStream()); - } catch(IOException e) { - LOG.e("IceCreamCordovaWebViewClient", "Error occurred while loading a file.", e); - } + if(ret == null && (url.contains("?") || url.contains("#") || needsIceCreamSpaceInAssetUrlFix(url))){ + ret = generateWebResourceResponse(url); } return ret; } + + private WebResourceResponse generateWebResourceResponse(String url) { + if (url.startsWith("file:///android_asset/")) { + String mimetype = FileHelper.getMimeType(url, cordova); + + try { + InputStream stream = FileHelper.getInputStreamFromUriString(url, cordova); + WebResourceResponse response = new WebResourceResponse(mimetype, "UTF-8", stream); + return response; + } catch (IOException e) { + LOG.e("generateWebResourceResponse", e.getMessage(), e); + } + } + return null; + } + + private static boolean needsIceCreamSpaceInAssetUrlFix(String url) { + if (!url.contains("%20")){ + return false; + } + + switch(android.os.Build.VERSION.SDK_INT){ + case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH: + case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1: + return true; + default: + return false; + } + } + } diff --git a/framework/src/org/apache/cordova/api/CordovaPlugin.java b/framework/src/org/apache/cordova/api/CordovaPlugin.java index 69f8fdeb..2b225e64 100644 --- a/framework/src/org/apache/cordova/api/CordovaPlugin.java +++ b/framework/src/org/apache/cordova/api/CordovaPlugin.java @@ -175,20 +175,6 @@ public class CordovaPlugin { return null; } - /** - * All plugins can now choose if they want to modify any uri requests. This includes all webview requests, opening of files, content uri's etc. - * This mechanism allows several plugins to modify the same request - * @param requestSource The source of the incoming request - * - * @param dataResource The resource to be loaded. - * @param dataResourceContext Context associated with the resource load - * @return Return a new DataResource if the plugin wants o assist in loading the request or null if it doesn't. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public DataResource shouldInterceptDataResourceRequest(DataResource dataResource, DataResourceContext dataResourceContext) { - return null; - } - /** * Called when the WebView does a top-level navigation or refreshes. * diff --git a/framework/src/org/apache/cordova/api/DataResource.java b/framework/src/org/apache/cordova/api/DataResource.java deleted file mode 100644 index 38bf31bf..00000000 --- a/framework/src/org/apache/cordova/api/DataResource.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. -*/ -package org.apache.cordova.api; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.apache.cordova.FileHelper; - -import android.net.Uri; - -/* - * All requests to access files, browser network requests etc have to go through this class. - */ -public class DataResource { - private CordovaInterface cordova; - - // Uri of the request. Always required. - private Uri uri; - // Remaining fields may or may not be null - private InputStream is; - private OutputStream os; - private String mimeType; - private Boolean writable; - private File realFile; - private boolean retryLoad = true; - - public DataResource(CordovaInterface cordova, Uri uri) { - super(); - this.cordova = cordova; - this.uri = uri; - } - public DataResource(CordovaInterface cordova, Uri uri, InputStream is, - OutputStream os, String mimeType, boolean writable, File realFile) { - this(cordova, uri); - this.is = is; - this.mimeType = mimeType; - this.writable = Boolean.valueOf(writable); - this.realFile = realFile; - } - public Uri getUri() { - // Uri is always provided - return uri; - } - public InputStream getIs() throws IOException { - if(is == null && retryLoad) { - try { - is = FileHelper.getInputStreamFromUriString(uri.toString(), cordova); - } finally { - // We failed loading once, don't try loading anymore - if(is == null) { - retryLoad = false; - } - } - } - return is; - } - public OutputStream getOs() throws FileNotFoundException { - if(os == null && retryLoad) { - try { - os = FileHelper.getOutputStreamFromUriString(uri.toString(), cordova); - } finally { - // We failed loading once, don't try loading anymore - if(os == null) { - retryLoad = false; - } - } - } - return os; - } - public String getMimeType() { - if(mimeType == null && retryLoad) { - try { - mimeType = FileHelper.getMimeType(uri.toString(), cordova); - } finally { - // We failed loading once, don't try loading anymore - if(mimeType == null) { - retryLoad = false; - } - } - } - return mimeType; - } - public boolean isWritable() { - if(writable == null && retryLoad) { - try { - writable = FileHelper.isUriWritable(uri.toString()); - } finally { - // We failed loading once, don't try loading anymore - if(writable == null) { - retryLoad = false; - } - } - } - // default to false - return writable != null? writable.booleanValue() : false; - } - public File getRealFile() { - if(realFile == null && retryLoad) { - try { - String realPath = FileHelper.getRealPath(uri, cordova); - if(realPath != null) { - realFile = new File(realPath); - } - } finally { - // We failed loading once, don't try loading anymore - if(realFile == null) { - retryLoad = false; - } - } - } - return realFile; - } - - // static instantiation methods - public static DataResource initiateNewDataRequestForUri(String uriString, PluginManager pluginManager, CordovaInterface cordova, String requestSourceTag){ - // if no protocol is specified, assume its file: - uriString = FileHelper.insertFileProtocol(uriString); - return initiateNewDataRequestForUri(Uri.parse(uriString), pluginManager, cordova, requestSourceTag); - } - public static DataResource initiateNewDataRequestForUri(Uri uri, PluginManager pluginManager, CordovaInterface cordova, String requestSourceTag){ - return initiateNewDataRequestForUri(uri, pluginManager, cordova, new DataResourceContext(requestSourceTag, false /* Assume, not a browser request by default */ )); - } - public static DataResource initiateNewDataRequestForUri(String uriString, PluginManager pluginManager, CordovaInterface cordova, DataResourceContext dataResourceContext){ - // if no protocol is specified, assume its file: - uriString = FileHelper.insertFileProtocol(uriString); - return initiateNewDataRequestForUri(Uri.parse(uriString), pluginManager, cordova, dataResourceContext); - } - public static DataResource initiateNewDataRequestForUri(Uri uri, PluginManager pluginManager, CordovaInterface cordova, DataResourceContext dataResourceContext){ - DataResource dataResource = new DataResource(cordova, uri); - if (pluginManager != null) { - // get the resource as returned by plugins - dataResource = pluginManager.shouldInterceptDataResourceRequest(dataResource, dataResourceContext); - } - return dataResource; - } -} diff --git a/framework/src/org/apache/cordova/api/DataResourceContext.java b/framework/src/org/apache/cordova/api/DataResourceContext.java deleted file mode 100644 index 55bbc1d0..00000000 --- a/framework/src/org/apache/cordova/api/DataResourceContext.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. -*/ -package org.apache.cordova.api; - -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -/* - * Some context information associated with a DataRequest. - */ -public class DataResourceContext { - // A random id that is unique for a particular request. - private int requestId; - // A tag associated with the source of this dataResourceContext - private String source; - // If needed, any data associated with core plugins can be a part of the context object - // This field indicates whether the request came from a browser network request - private boolean isFromBrowser; - // If needed, any data associated with non core plugins should store data in a Map so as to not clutter the context object - private Map dataMap; - public DataResourceContext(String source, boolean isFromBrowser) { - super(); - this.requestId = new Random().nextInt(); - this.source = source; - this.isFromBrowser = isFromBrowser; - this.dataMap = new HashMap(); - } - public int getRequestId() { - return requestId; - } - public String getSource() { - return source; - } - public boolean isFromBrowser() { - return isFromBrowser; - } - public Map getDataMap() { - return dataMap; - } -} diff --git a/framework/src/org/apache/cordova/api/PluginManager.java b/framework/src/org/apache/cordova/api/PluginManager.java index 36ac357e..71fc2581 100755 --- a/framework/src/org/apache/cordova/api/PluginManager.java +++ b/framework/src/org/apache/cordova/api/PluginManager.java @@ -400,30 +400,4 @@ public class PluginManager { LOG.e(TAG, "https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=blob;f=framework/res/xml/plugins.xml"); LOG.e(TAG, "====================================================================================="); } - - /** - * Called when the any resource is going to be loaded - either from the webview, files or any other resource - * - * - * @param dataResource The resource request to be loaded. - * @param dataResourceContext The context of the dataResource request - * @return Return the resource request that will be loaded. The returned request may be modified or unchanged. - */ - public DataResource shouldInterceptDataResourceRequest(DataResource dataResource, DataResourceContext dataResourceContext){ - boolean requestModified = true; - while(requestModified) { - requestModified = false; - for (PluginEntry entry : this.entries.values()) { - if (entry.plugin != null) { - DataResource ret = entry.plugin.shouldInterceptDataResourceRequest(dataResource, dataResourceContext); - if(ret != null) { - dataResource = ret; - requestModified = true; - break; - } - } - } - } - return dataResource; - } }