You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ia...@apache.org on 2013/12/13 17:18:50 UTC
[08/19] git commit: CB-5407: Start refactoring android code: Modular
filesystems, rfs, rlfsurl
CB-5407: Start refactoring android code: Modular filesystems, rfs, rlfsurl
Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/30988f70
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/30988f70
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/30988f70
Branch: refs/heads/dev
Commit: 30988f707b33ca4c140e0ae356cdbfa29761008a
Parents: 225c905
Author: Ian Clelland <ic...@chromium.org>
Authored: Sun Nov 24 22:47:19 2013 -0500
Committer: Ian Clelland <ic...@chromium.org>
Committed: Fri Dec 13 11:00:09 2013 -0500
----------------------------------------------------------------------
src/android/ContentFilesystem.java | 53 ++++++++++++++
src/android/FileUtils.java | 121 ++++++++++++++++++-------------
src/android/Filesystem.java | 11 +++
src/android/LocalFilesystem.java | 50 +++++++++++++
src/android/LocalFilesystemURL.java | 54 ++++++++++++++
5 files changed, 238 insertions(+), 51 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/30988f70/src/android/ContentFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java
new file mode 100644
index 0000000..bef40a3
--- /dev/null
+++ b/src/android/ContentFilesystem.java
@@ -0,0 +1,53 @@
+package org.apache.cordova.file;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.apache.cordova.CordovaInterface;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.database.Cursor;
+import android.provider.MediaStore;
+
+public class ContentFilesystem implements Filesystem {
+
+ private CordovaInterface cordova;
+
+ public ContentFilesystem(CordovaInterface cordova) {
+ this.cordova = cordova;
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {
+ File fp = null;
+
+ Cursor cursor = this.cordova.getActivity().managedQuery(inputURL.URL, new String[] { MediaStore.Images.Media.DATA }, null, null, null);
+ // Note: MediaStore.Images/Audio/Video.Media.DATA is always "_data"
+ int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+ cursor.moveToFirst();
+ fp = new File(cursor.getString(column_index));
+
+ if (!fp.exists()) {
+ throw new FileNotFoundException();
+ }
+ if (!fp.canRead()) {
+ throw new IOException();
+ }
+ try {
+ JSONObject entry = new JSONObject();
+ entry.put("isFile", fp.isFile());
+ entry.put("isDirectory", fp.isDirectory());
+ entry.put("name", fp.getName());
+ entry.put("fullPath", "file://" + fp.getAbsolutePath());
+ // The file system can't be specified, as it would lead to an infinite loop.
+ entry.put("filesystem", FileUtils.APPLICATION);
+ return entry;
+ } catch (JSONException e) {
+ throw new IOException();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/30988f70/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index 2a6bddf..8c069b5 100755
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -18,15 +18,15 @@
*/
package org.apache.cordova.file;
-import android.database.Cursor;
-import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
@@ -42,9 +42,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
-import java.net.URL;
import java.net.URLDecoder;
import java.nio.channels.FileChannel;
+import java.util.ArrayList;
/**
* This class provides SD card file and directory services to JavaScript.
@@ -75,7 +75,41 @@ public class FileUtils extends CordovaPlugin {
private interface FileOp {
void run( ) throws Exception;
}
-
+
+ private ArrayList<Filesystem> filesystems;
+
+ @Override
+ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
+ super.initialize(cordova, webView);
+ this.filesystems = new ArrayList<Filesystem>();
+
+ File fp;
+ String tempRoot;
+ String persistentRoot;
+ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath();
+ tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() +
+ "/Android/data/" + cordova.getActivity().getPackageName() + "/cache/";
+ } else {
+ persistentRoot = "/data/data/" + cordova.getActivity().getPackageName();
+ tempRoot = "/data/data/" + cordova.getActivity().getPackageName() + "/cache/";
+ }
+ // Create the cache dir if it doesn't exist.
+ fp = new File(tempRoot);
+ fp.mkdirs();
+ this.filesystems.add(new LocalFilesystem(cordova, "temporary", tempRoot));
+ this.filesystems.add(new LocalFilesystem(cordova, "persistent", persistentRoot));
+ this.filesystems.add(new ContentFilesystem(cordova));
+ }
+
+ public Filesystem filesystemForURL(LocalFilesystemURL localURL) {
+ try {
+ return this.filesystems.get(localURL.filesystemType);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return null;
+ }
+ }
+
/**
* Executes the request and returns whether the action was valid.
*
@@ -377,45 +411,21 @@ public class FileUtils extends CordovaPlugin {
* @throws IOException if the user can't read the file
* @throws JSONException
*/
- @SuppressWarnings("deprecation")
private JSONObject resolveLocalFileSystemURI(String url) throws IOException, JSONException {
String decoded = URLDecoder.decode(url, "UTF-8");
- File fp = null;
-
- // Handle the special case where you get an Android content:// uri.
- if (decoded.startsWith("content:")) {
- Cursor cursor = this.cordova.getActivity().managedQuery(Uri.parse(decoded), new String[] { MediaStore.Images.Media.DATA }, null, null, null);
- // Note: MediaStore.Images/Audio/Video.Media.DATA is always "_data"
- int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
- cursor.moveToFirst();
- fp = new File(cursor.getString(column_index));
- } else {
- // Test to see if this is a valid URL first
- @SuppressWarnings("unused")
- URL testUrl = new URL(decoded);
-
- if (decoded.startsWith("file://")) {
- int questionMark = decoded.indexOf("?");
- if (questionMark < 0) {
- fp = new File(decoded.substring(7, decoded.length()));
- } else {
- fp = new File(decoded.substring(7, questionMark));
- }
- } else {
- fp = new File(decoded);
- }
- }
-
- if (!fp.exists()) {
- throw new FileNotFoundException();
- }
- if (!fp.canRead()) {
- throw new IOException();
- }
- return getEntry(fp);
- }
-
+ try {
+ LocalFilesystemURL inputURL = new LocalFilesystemURL(decoded);
+ Filesystem fs = this.filesystemForURL(inputURL);
+ if (fs == null) {
+ throw new MalformedURLException("Unrecognized filesystem URL");
+ }
+ return fs.getEntryForLocalURL(inputURL);
+ } catch (IllegalArgumentException e) {
+ throw new IOException();
+ }
+ }
+
/**
* Read the list of files from this directory.
*
@@ -1001,10 +1011,27 @@ public class FileUtils extends CordovaPlugin {
else {
throw new IOException("No filesystem of type requested");
}
-
+ fs.put("root", makeEntryForPath("/", type, true));
return fs;
}
+ public static JSONObject makeEntryForPath(String path, int fsType, Boolean isDir) throws JSONException {
+ JSONObject entry = new JSONObject();
+
+ int end = path.endsWith("/") ? 1 : 0;
+ String[] parts = path.substring(0,path.length()-end).split("/",1);
+ String name = parts[parts.length-1];
+ entry.put("isFile", !isDir);
+ entry.put("isDirectory", isDir);
+ entry.put("name", name);
+ entry.put("fullPath", path);
+ // The file system can't be specified, as it would lead to an infinite loop,
+ // but the filesystem type can
+ entry.put("filesystem", fsType);
+
+ return entry;
+
+ }
/**
* Returns a JSON object representing the given File.
*
@@ -1012,17 +1039,9 @@ public class FileUtils extends CordovaPlugin {
* @return a JSON representation of the given File
* @throws JSONException
*/
+ @Deprecated
public static JSONObject getEntry(File file) throws JSONException {
- JSONObject entry = new JSONObject();
-
- entry.put("isFile", file.isFile());
- entry.put("isDirectory", file.isDirectory());
- entry.put("name", file.getName());
- entry.put("fullPath", "file://" + file.getAbsolutePath());
- // The file system can't be specified, as it would lead to an infinite loop.
- // entry.put("filesystem", null);
-
- return entry;
+ return makeEntryForPath(file.getAbsolutePath(), 0, file.isDirectory());
}
/**
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/30988f70/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
new file mode 100644
index 0000000..1879ad0
--- /dev/null
+++ b/src/android/Filesystem.java
@@ -0,0 +1,11 @@
+package org.apache.cordova.file;
+
+import java.io.IOException;
+
+import org.json.JSONObject;
+
+public interface Filesystem {
+
+ JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/30988f70/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
new file mode 100644
index 0000000..c005867
--- /dev/null
+++ b/src/android/LocalFilesystem.java
@@ -0,0 +1,50 @@
+package org.apache.cordova.file;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.util.Base64;
+
+public class LocalFilesystem implements Filesystem {
+
+ private String name;
+ private String fsRoot;
+ private CordovaInterface cordova;
+
+ public LocalFilesystem(CordovaInterface cordova, String name, String fsRoot) {
+ this.name = name;
+ this.fsRoot = fsRoot;
+ this.cordova = cordova;
+ }
+
+ @Override
+ public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {
+ File fp = null;
+ fp = new File(this.fsRoot + inputURL.fullPath); //TODO: Proper fs.join
+
+ if (!fp.exists()) {
+ throw new FileNotFoundException();
+ }
+ if (!fp.canRead()) {
+ throw new IOException();
+ }
+ try {
+ JSONObject entry = new JSONObject();
+ entry.put("isFile", fp.isFile());
+ entry.put("isDirectory", fp.isDirectory());
+ entry.put("name", fp.getName());
+ entry.put("fullPath", "file://" + fp.getAbsolutePath());
+ // The file system can't be specified, as it would lead to an infinite loop.
+ // But we can specify the type of FS, and the rest can be reconstructed in JS.
+ entry.put("filesystem", inputURL.filesystemType);
+ return entry;
+ } catch (JSONException e) {
+ throw new IOException();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/30988f70/src/android/LocalFilesystemURL.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystemURL.java b/src/android/LocalFilesystemURL.java
new file mode 100644
index 0000000..0dc547e
--- /dev/null
+++ b/src/android/LocalFilesystemURL.java
@@ -0,0 +1,54 @@
+package org.apache.cordova.file;
+
+import android.net.Uri;
+
+public class LocalFilesystemURL {
+ public static final int TEMPORARY = 0;
+ public static final int PERSISTENT = 1;
+
+ Uri URL;
+ int filesystemType;
+ String fullPath;
+
+ public LocalFilesystemURL(Uri URL) {
+ this.URL = URL;
+ this.filesystemType = this.filesystemTypeForLocalURL(URL);
+ this.fullPath = this.fullPathForLocalURL(URL);
+ }
+
+ private String fullPathForLocalURL(Uri URL) {
+ int fsType = this.filesystemTypeForLocalURL(URL);
+ if (fsType == FileUtils.TEMPORARY) {
+ return URL.getPath().substring(10);
+ }
+ if (fsType == FileUtils.PERSISTENT) {
+ return URL.getPath().substring(11);
+ }
+ if (fsType == FileUtils.APPLICATION) {
+ return URL.getPath();
+ }
+ return null;
+ }
+
+ private int filesystemTypeForLocalURL(Uri URL) {
+ if ("filesystem".equals(URL.getScheme()) && "localhost".equals(URL.getHost())) {
+ String path = URL.getPath();
+ if (path != null) {
+ if (path.startsWith("/temporary")) {
+ return FileUtils.TEMPORARY;
+ } else if (path.startsWith("/persistent")) {
+ return FileUtils.PERSISTENT;
+ }
+ }
+ } else if ("content".equals(URL.getScheme())) {
+ return FileUtils.APPLICATION;
+ }
+ return -1;
+ }
+
+ public LocalFilesystemURL(String strURL) {
+ this(Uri.parse(strURL));
+ }
+
+
+}