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:02 UTC

[06/15] 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/96d632fc
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/96d632fc
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/96d632fc

Branch: refs/heads/android-file
Commit: 96d632fc349bae32643aba2830f7cf1b4d8b4f52
Parents: abf2c05
Author: Ian Clelland <ic...@chromium.org>
Authored: Sun Nov 24 22:47:19 2013 -0500
Committer: Ian Clelland <ic...@chromium.org>
Committed: Wed Dec 11 09:57:57 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/96d632fc/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/96d632fc/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index 29026f0..473af3e 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/96d632fc/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/96d632fc/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/96d632fc/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));
+	}
+	
+	
+}