You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2015/03/11 16:35:12 UTC
[01/13] cordova-plugin-file git commit: CB-8642 android: Fix content
URIs not working with resolve / copy
Repository: cordova-plugin-file
Updated Branches:
refs/heads/master 2ed379c7c -> 80cf1de40
CB-8642 android: Fix content URIs not working with resolve / copy
The issue was fairly fundamental to our cdvfile:// scheme and required
some refactorings:
- Move isDirectory into LocalFilesystemURL
- Add toNativeUri() / toLocalUri() for converting between cdvfile: / file: / content:
- Made toInternalUrl() maintain query params for content: uris
- Moved copyFileToURL(), readFileAtURL(), getOutputStreamForURL() into base Filesystem class
Also added a ContentProvider to the test plugin and unit tests!
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/d6202261
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/d6202261
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/d6202261
Branch: refs/heads/master
Commit: d6202261fec395854050e771d262afcf4d4e86d9
Parents: 9d78908
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Mar 10 13:54:33 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
src/android/ContentFilesystem.java | 197 +++++++++---------------
src/android/FileUtils.java | 50 +++---
src/android/Filesystem.java | 124 ++++++++-------
src/android/LocalFilesystem.java | 141 ++++++++---------
src/android/LocalFilesystemURL.java | 27 ++--
tests/plugin.xml | 10 ++
tests/src/android/TestContentProvider.java | 78 ++++++++++
tests/tests.js | 75 ++++++---
www/Entry.js | 2 +-
www/FileSystem.js | 2 +-
www/android/FileSystem.js | 13 +-
11 files changed, 404 insertions(+), 315 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/src/android/ContentFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java
index a4a2227..25c6489 100644
--- a/src/android/ContentFilesystem.java
+++ b/src/android/ContentFilesystem.java
@@ -23,14 +23,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaResourceApi;
-import org.apache.cordova.CordovaWebView;
-import org.apache.cordova.PluginManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -50,68 +43,67 @@ public class ContentFilesystem extends Filesystem {
super(Uri.parse("content://"), "content", resourceApi);
this.context = context;
}
-
- @Override
- public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {
- if ("/".equals(inputURL.uri.getPath())) {
- return LocalFilesystem.makeEntryForURL(inputURL, true, inputURL.uri);
- }
- // Get the cursor to validate that the file exists
- Cursor cursor = openCursorForURL(inputURL);
- File file = resourceApi.mapUriToFile(inputURL.uri);
- Uri nativeUrl;
- if (file == null) {
- nativeUrl = inputURL.uri;
- } else {
- nativeUrl = Uri.fromFile(file);
- }
- return makeEntryForURL(inputURL, false /*fp.isDirectory()*/, nativeUrl);
- }
-
@Override
- public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
- String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException {
- if (options != null) {
- if (options.optBoolean("create")) {
- throw new IOException("Cannot create content url");
- }
+ public Uri toNativeUri(LocalFilesystemURL inputURL) {
+ String authorityAndPath = inputURL.uri.getEncodedPath().substring(this.name.length() + 2);
+ if (authorityAndPath.length() < 2) {
+ return null;
}
- LocalFilesystemURL requestedURL = LocalFilesystemURL.parse(Uri.withAppendedPath(inputURL.uri, fileName));
- File fp = new File(this.filesystemPathForURL(requestedURL));
- if (!fp.exists()) {
- throw new FileNotFoundException("path does not exist");
+ String ret = "content://" + authorityAndPath;
+ String query = inputURL.uri.getEncodedQuery();
+ if (query != null) {
+ ret += '?' + query;
}
- if (directory) {
- if (fp.isFile()) {
- throw new TypeMismatchException("path doesn't exist or is file");
- }
- } else {
- if (fp.isDirectory()) {
- throw new TypeMismatchException("path doesn't exist or is directory");
- }
+ String frag = inputURL.uri.getEncodedFragment();
+ if (frag != null) {
+ ret += '#' + frag;
}
- // Return the directory
- return makeEntryForURL(requestedURL, directory, Uri.fromFile(fp));
+ return Uri.parse(ret);
+ }
+
+ @Override
+ public LocalFilesystemURL toLocalUri(Uri inputURL) {
+ if (!"content".equals(inputURL.getScheme())) {
+ return null;
+ }
+ String subPath = inputURL.getEncodedPath();
+ if (subPath.length() > 0) {
+ subPath = subPath.substring(1);
+ }
+ Uri.Builder b = new Uri.Builder()
+ .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL)
+ .authority("localhost")
+ .path(name)
+ .appendPath(inputURL.getAuthority());
+ if (subPath.length() > 0) {
+ b.appendEncodedPath(subPath);
+ }
+ Uri localUri = b.encodedQuery(inputURL.getEncodedQuery())
+ .encodedFragment(inputURL.getEncodedFragment())
+ .build();
+ return LocalFilesystemURL.parse(localUri);
+ }
+ @Override
+ public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
+ String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException {
+ throw new UnsupportedOperationException("getFile() not supported for content:. Use resolveLocalFileSystemURL instead.");
}
@Override
public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL)
throws NoModificationAllowedException {
-
- String filePath = filesystemPathForURL(inputURL);
- File file = new File(filePath);
+ Uri contentUri = toNativeUri(inputURL);
try {
- context.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- MediaStore.Images.Media.DATA + " = ?",
- new String[] { filePath });
+ context.getContentResolver().delete(contentUri, null, null);
} catch (UnsupportedOperationException t) {
// Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
// The ContentResolver applies only when the file was registered in the
// first case, which is generally only the case with images.
+ throw new NoModificationAllowedException("Deleting not supported for content uri: " + contentUri);
}
- return file.delete();
+ return true;
}
@Override
@@ -123,22 +115,27 @@ public class ContentFilesystem extends Filesystem {
@Override
public JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL)
throws FileNotFoundException {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("readEntriesAtLocalURL() not supported for content:. Use resolveLocalFileSystemURL instead.");
}
@Override
public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
- Integer size = null;
- Integer lastModified = null;
- Cursor cursor = openCursorForURL(inputURL);
+ long size = -1;
+ long lastModified = 0;
+ Uri nativeUri = toNativeUri(inputURL);
+ String mimeType = resourceApi.getMimeType(nativeUri);
+ Cursor cursor = openCursorForURL(nativeUri);
try {
if (cursor != null && cursor.moveToFirst()) {
size = resourceSizeForCursor(cursor);
lastModified = lastModifiedDateForCursor(cursor);
} else {
- throw new FileNotFoundException();
+ // Some content providers don't support cursors at all!
+ CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(nativeUri);
+ size = offr.length;
}
+ } catch (IOException e) {
+ throw new FileNotFoundException();
} finally {
if (cursor != null)
cursor.close();
@@ -147,9 +144,9 @@ public class ContentFilesystem extends Filesystem {
JSONObject metadata = new JSONObject();
try {
metadata.put("size", size);
- metadata.put("type", resourceApi.getMimeType(inputURL.uri));
+ metadata.put("type", mimeType);
metadata.put("name", name);
- metadata.put("fullPath", inputURL.pathAndQuery);
+ metadata.put("fullPath", inputURL.path);
metadata.put("lastModifiedDate", lastModified);
} catch (JSONException e) {
return null;
@@ -158,56 +155,6 @@ public class ContentFilesystem extends Filesystem {
}
@Override
- public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
- Filesystem srcFs, LocalFilesystemURL srcURL, boolean move)
- throws IOException, InvalidModificationException, JSONException,
- NoModificationAllowedException, FileExistsException {
- if (LocalFilesystem.class.isInstance(srcFs)) {
- /* Same FS, we can shortcut with CordovaResourceApi operations */
- // Figure out where we should be copying to
- final LocalFilesystemURL destinationURL = makeDestinationURL(newName, srcURL, destURL);
-
- OutputStream os = resourceApi.openOutputStream(destURL.uri);
- CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(srcURL.uri);
- if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {
- throw new NoModificationAllowedException("Cannot move file at source URL");
- }
- try {
- resourceApi.copyResource(ofrr, os);
- } catch (IOException e) {
- throw new IOException("Cannot read file at source URL");
- }
- if (move) {
- srcFs.removeFileAtLocalURL(srcURL);
- }
- return makeEntryForURL(destinationURL, false, destinationURL.uri);
- } else {
- // Need to copy the hard way
- return super.copyFileToURL(destURL, newName, srcFs, srcURL, move);
- }
- }
-
-
- @Override
- public void readFileAtURL(LocalFilesystemURL inputURL, long start, long end,
- ReadFileCallback readFileCallback) throws IOException {
- CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(inputURL.uri);
- if (end < 0) {
- end = ofrr.length;
- }
- long numBytesToRead = end - start;
- try {
- if (start > 0) {
- ofrr.inputStream.skip(start);
- }
- LimitedInputStream inputStream = new LimitedInputStream(ofrr.inputStream, numBytesToRead);
- readFileCallback.handleData(inputStream, ofrr.mimeType);
- } finally {
- ofrr.inputStream.close();
- }
- }
-
- @Override
public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
int offset, boolean isBinary) throws NoModificationAllowedException {
throw new NoModificationAllowedException("Couldn't write to file given its content URI");
@@ -218,30 +165,33 @@ public class ContentFilesystem extends Filesystem {
throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
}
- protected Cursor openCursorForURL(LocalFilesystemURL url) {
+ protected Cursor openCursorForURL(Uri nativeUri) {
ContentResolver contentResolver = context.getContentResolver();
- Cursor cursor = contentResolver.query(url.uri, null, null, null, null);
- return cursor;
+ try {
+ return contentResolver.query(nativeUri, null, null, null, null);
+ } catch (UnsupportedOperationException e) {
+ return null;
+ }
}
- protected Integer resourceSizeForCursor(Cursor cursor) {
+ private Long resourceSizeForCursor(Cursor cursor) {
int columnIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
if (columnIndex != -1) {
String sizeStr = cursor.getString(columnIndex);
if (sizeStr != null) {
- return Integer.parseInt(sizeStr,10);
+ return Long.parseLong(sizeStr);
}
}
return null;
}
- protected Integer lastModifiedDateForCursor(Cursor cursor) {
+ protected Long lastModifiedDateForCursor(Cursor cursor) {
final String[] LOCAL_FILE_PROJECTION = { MediaStore.MediaColumns.DATE_MODIFIED };
int columnIndex = cursor.getColumnIndex(LOCAL_FILE_PROJECTION[0]);
if (columnIndex != -1) {
String dateStr = cursor.getString(columnIndex);
if (dateStr != null) {
- return Integer.parseInt(dateStr,10);
+ return Long.parseLong(dateStr);
}
}
return null;
@@ -249,7 +199,7 @@ public class ContentFilesystem extends Filesystem {
@Override
public String filesystemPathForURL(LocalFilesystemURL url) {
- File f = resourceApi.mapUriToFile(url.uri);
+ File f = resourceApi.mapUriToFile(toNativeUri(url));
return f == null ? null : f.getAbsolutePath();
}
@@ -261,15 +211,6 @@ public class ContentFilesystem extends Filesystem {
@Override
public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
- String path = filesystemPathForURL(inputURL);
- File file = new File(path);
- return file.exists();
+ return true;
}
-
- @Override
- OutputStream getOutputStreamForURL(LocalFilesystemURL inputURL)
- throws IOException {
- OutputStream os = resourceApi.openOutputStream(inputURL.uri);
- return os;
- }
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index 2a1e965..a810726 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -41,7 +41,6 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
-import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -503,6 +502,24 @@ public class FileUtils extends CordovaPlugin {
return true;
}
+ public LocalFilesystemURL resolveNativeUri(Uri nativeUri) {
+ LocalFilesystemURL localURL = null;
+
+ // Try all installed filesystems. Return the best matching URL
+ // (determined by the shortest resulting URL)
+ for (Filesystem fs : filesystems) {
+ LocalFilesystemURL url = fs.toLocalUri(nativeUri);
+ if (url != null) {
+ // A shorter fullPath implies that the filesystem is a better
+ // match for the local path than the previous best.
+ if (localURL == null || (url.uri.toString().length() < localURL.toString().length())) {
+ localURL = url;
+ }
+ }
+ }
+ return localURL;
+ }
+
/*
* These two native-only methods can be used by other plugins to translate between
* device file system paths and URLs. By design, there is no direct JavaScript
@@ -529,15 +546,13 @@ public class FileUtils extends CordovaPlugin {
// Try all installed filesystems. Return the best matching URL
// (determined by the shortest resulting URL)
for (Filesystem fs: filesystems) {
- if (fs != null) {
- LocalFilesystemURL url = fs.URLforFilesystemPath(localPath);
- if (url != null) {
- // A shorter fullPath implies that the filesystem is a better
- // match for the local path than the previous best.
- if (localURL == null || (url.pathAndQuery.length() < shortestFullPath)) {
- localURL = url;
- shortestFullPath = url.pathAndQuery.length();
- }
+ LocalFilesystemURL url = fs.URLforFilesystemPath(localPath);
+ if (url != null) {
+ // A shorter fullPath implies that the filesystem is a better
+ // match for the local path than the previous best.
+ if (localURL == null || (url.path.length() < shortestFullPath)) {
+ localURL = url;
+ shortestFullPath = url.path.length();
}
}
}
@@ -592,18 +607,15 @@ public class FileUtils extends CordovaPlugin {
* @throws JSONException
*/
private JSONObject resolveLocalFileSystemURI(String uriString) throws IOException, JSONException {
- LocalFilesystemURL inputURL;
if (uriString == null) {
throw new MalformedURLException("Unrecognized filesystem URL");
}
Uri uri = Uri.parse(uriString);
- /* Backwards-compatibility: Check for file:// urls */
- if ("file".equals(uri.getScheme())) {
- String path = uri.getPath();
- inputURL = this.filesystemURLforLocalPath(path);
- } else {
- inputURL = LocalFilesystemURL.parse(uri);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri);
+ if (inputURL == null) {
+ /* Check for file://, content:// urls */
+ inputURL = resolveNativeUri(uri);
}
try {
@@ -687,7 +699,7 @@ public class FileUtils extends CordovaPlugin {
try {
LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
// You can't delete the root directory.
- if ("".equals(inputURL.pathAndQuery) || "/".equals(inputURL.pathAndQuery)) {
+ if ("".equals(inputURL.path) || "/".equals(inputURL.path)) {
throw new NoModificationAllowedException("You can't delete the root directory");
}
@@ -716,7 +728,7 @@ public class FileUtils extends CordovaPlugin {
try {
LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
// You can't delete the root directory.
- if ("".equals(inputURL.pathAndQuery) || "/".equals(inputURL.pathAndQuery)) {
+ if ("".equals(inputURL.path) || "/".equals(inputURL.path)) {
throw new NoModificationAllowedException("You can't delete the root directory");
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index 64b78b8..2d64942 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -43,34 +43,36 @@ public abstract class Filesystem {
this.rootUri = rootUri;
this.name = name;
this.resourceApi = resourceApi;
- rootEntry = makeEntryForPath("/", name, true, rootUri.toString());
+ rootEntry = makeEntryForNativeUri(rootUri);
}
public interface ReadFileCallback {
public void handleData(InputStream inputStream, String contentType) throws IOException;
}
- public static JSONObject makeEntryForPath(String path, String fsName, Boolean isDir, String nativeURL) {
+ public static JSONObject makeEntryForURL(LocalFilesystemURL inputURL, Uri nativeURL) {
try {
- JSONObject entry = new JSONObject();
-
+ String path = inputURL.path;
int end = path.endsWith("/") ? 1 : 0;
String[] parts = path.substring(0, path.length() - end).split("/+");
String fileName = parts[parts.length - 1];
- entry.put("isFile", !isDir);
- entry.put("isDirectory", isDir);
+
+ JSONObject entry = new JSONObject();
+ entry.put("isFile", !inputURL.isDirectory);
+ entry.put("isDirectory", inputURL.isDirectory);
entry.put("name", fileName);
entry.put("fullPath", path);
// The file system can't be specified, as it would lead to an infinite loop,
// but the filesystem name can be.
- entry.put("filesystemName", fsName);
+ entry.put("filesystemName", inputURL.fsName);
// Backwards compatibility
- entry.put("filesystem", "temporary".equals(fsName) ? 0 : 1);
+ entry.put("filesystem", "temporary".equals(inputURL.fsName) ? 0 : 1);
- if (isDir && !nativeURL.endsWith("/")) {
- nativeURL += "/";
+ String nativeUrlStr = nativeURL.toString();
+ if (inputURL.isDirectory && !nativeUrlStr.endsWith("/")) {
+ nativeUrlStr += "/";
}
- entry.put("nativeURL", nativeURL);
+ entry.put("nativeURL", nativeUrlStr);
return entry;
} catch (JSONException e) {
e.printStackTrace();
@@ -78,13 +80,21 @@ public abstract class Filesystem {
}
}
- public static JSONObject makeEntryForURL(LocalFilesystemURL inputURL, Boolean isDir, Uri nativeURL) {
- return makeEntryForPath(inputURL.pathAndQuery, inputURL.fsName, isDir, nativeURL.toString());
+ public JSONObject makeEntryForURL(LocalFilesystemURL inputURL) {
+ Uri nativeUri = toNativeUri(inputURL);
+ return makeEntryForURL(inputURL, nativeUri);
+ }
+
+ public JSONObject makeEntryForNativeUri(Uri nativeUri) {
+ LocalFilesystemURL inputUrl = toLocalUri(nativeUri);
+ return makeEntryForURL(inputUrl, nativeUri);
}
- abstract JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException;
+ public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {
+ return makeEntryForURL(inputURL);
+ }
- abstract JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, String path,
+ abstract JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, String path,
JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException;
abstract boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException;
@@ -99,6 +109,9 @@ public abstract class Filesystem {
return rootUri;
}
+ public abstract Uri toNativeUri(LocalFilesystemURL inputURL);
+ public abstract LocalFilesystemURL toLocalUri(Uri inputURL);
+
public JSONObject getRootEntry() {
return rootEntry;
}
@@ -126,57 +139,60 @@ public abstract class Filesystem {
}
return LocalFilesystemURL.parse(newDest);
}
-
+
/* Read a source URL (possibly from a different filesystem, srcFs,) and copy it to
* the destination URL on this filesystem, optionally with a new filename.
* If move is true, then this method should either perform an atomic move operation
* or remove the source file when finished.
*/
- JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
+ public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {
- // This is "the hard way" -- transfer data between arbitrary filesystem urls/
- // Gets an input stream from src, and writes its contents to an output stream
- // from dest.
-
// First, check to see that we can do it
- if (!move || srcFs.canRemoveFileAtLocalURL(srcURL)) {
- final LocalFilesystemURL destination = makeDestinationURL(newName, srcURL, destURL);
- srcFs.readFileAtURL(srcURL, 0, -1, new ReadFileCallback() {
- public void handleData(InputStream inputStream, String contentType) throws IOException {
- if (inputStream != null) {
- //write data to file
- OutputStream os = getOutputStreamForURL(destination);
- final int BUFFER_SIZE = 8192;
- byte[] buffer = new byte[BUFFER_SIZE];
-
- for (;;) {
- int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE);
-
- if (bytesRead <= 0) {
- break;
- }
- os.write(buffer, 0, bytesRead);
- }
- os.close();
- } else {
- throw new IOException("Cannot read file at source URL");
- }
- }
- });
- if (move) {
- // Delete original
- srcFs.removeFileAtLocalURL(srcURL);
- }
- return getEntryForLocalURL(destination);
- } else {
+ if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {
throw new NoModificationAllowedException("Cannot move file at source URL");
}
+ final LocalFilesystemURL destination = makeDestinationURL(newName, srcURL, destURL);
+
+ Uri srcNativeUri = srcFs.toNativeUri(srcURL);
+
+ CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(srcNativeUri);
+ OutputStream os = null;
+ try {
+ os = getOutputStreamForURL(destination);
+ } catch (IOException e) {
+ ofrr.inputStream.close();
+ throw e;
+ }
+ // Closes streams.
+ resourceApi.copyResource(ofrr, os);
+
+ if (move) {
+ srcFs.removeFileAtLocalURL(srcURL);
+ }
+ return getEntryForLocalURL(destination);
}
- abstract OutputStream getOutputStreamForURL(LocalFilesystemURL inputURL) throws IOException;
+ public OutputStream getOutputStreamForURL(LocalFilesystemURL inputURL) throws IOException {
+ return resourceApi.openOutputStream(toNativeUri(inputURL));
+ }
- abstract void readFileAtURL(LocalFilesystemURL inputURL, long start, long end,
- ReadFileCallback readFileCallback) throws IOException;
+ public void readFileAtURL(LocalFilesystemURL inputURL, long start, long end,
+ ReadFileCallback readFileCallback) throws IOException {
+ CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(toNativeUri(inputURL));
+ if (end < 0) {
+ end = ofrr.length;
+ }
+ long numBytesToRead = end - start;
+ try {
+ if (start > 0) {
+ ofrr.inputStream.skip(start);
+ }
+ LimitedInputStream inputStream = new LimitedInputStream(ofrr.inputStream, numBytesToRead);
+ readFileCallback.handleData(inputStream, ofrr.mimeType);
+ } finally {
+ ofrr.inputStream.close();
+ }
+ }
abstract long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset,
boolean isBinary) throws NoModificationAllowedException, IOException;
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 805eacd..2754b41 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -24,14 +24,11 @@ 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.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
-import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaResourceApi;
import org.json.JSONArray;
import org.json.JSONException;
@@ -41,13 +38,12 @@ import android.util.Base64;
import android.net.Uri;
import android.content.Context;
import android.content.Intent;
-import android.app.Activity;
public class LocalFilesystem extends Filesystem {
private final Context context;
public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, String rootPath) {
- this(name, context, resourceApi, Uri.fromFile(new File(rootPath)));
+ this(name, context, resourceApi, Uri.fromFile(new File(rootPath)).buildUpon().appendPath("").build());
}
public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, Uri rootUri) {
super(rootUri, name, resourceApi);
@@ -55,50 +51,91 @@ public class LocalFilesystem extends Filesystem {
}
public String filesystemPathForFullPath(String fullPath) {
- String path = new File(rootUri.getPath(), fullPath).toString();
- int questionMark = path.indexOf("?");
- if (questionMark >= 0) {
- path = path.substring(0, questionMark);
- }
- if (path.length() > 1 && path.endsWith("/")) {
- path = path.substring(0, path.length()-1);
- }
- return path;
+ return new File(rootUri.getPath(), fullPath).toString();
}
@Override
public String filesystemPathForURL(LocalFilesystemURL url) {
- return filesystemPathForFullPath(url.pathAndQuery);
+ return filesystemPathForFullPath(url.path);
}
private String fullPathForFilesystemPath(String absolutePath) {
if (absolutePath != null && absolutePath.startsWith(rootUri.getPath())) {
- return absolutePath.substring(rootUri.getPath().length());
+ return absolutePath.substring(rootUri.getPath().length() - 1);
}
return null;
}
+ private Uri nativeUriForFullPath(String fullPath) {
+ Uri ret = null;
+ if (fullPath != null) {
+ String encodedPath = Uri.fromFile(new File(fullPath)).getEncodedPath();
+ if (encodedPath.startsWith("/")) {
+ encodedPath = encodedPath.substring(1);
+ }
+ ret = rootUri.buildUpon().appendEncodedPath(encodedPath).build();
+ }
+ return ret;
+ }
+
protected LocalFilesystemURL URLforFullPath(String fullPath) {
- if (fullPath != null) {
- if (fullPath.startsWith("/")) {
- return LocalFilesystemURL.parse(LocalFilesystemURL.FILESYSTEM_PROTOCOL + "://localhost/"+this.name+fullPath);
- }
- return LocalFilesystemURL.parse(LocalFilesystemURL.FILESYSTEM_PROTOCOL + "://localhost/"+this.name+"/"+fullPath);
+ Uri nativeUri = nativeUriForFullPath(fullPath);
+ if (nativeUri != null) {
+ return toLocalUri(nativeUri);
}
return null;
-
}
+
+ @Override
+ public Uri toNativeUri(LocalFilesystemURL inputURL) {
+ return nativeUriForFullPath(inputURL.path);
+ }
+
+ @Override
+ public LocalFilesystemURL toLocalUri(Uri inputURL) {
+ if (!"file".equals(inputURL.getScheme())) {
+ return null;
+ }
+ File f = new File(inputURL.getPath());
+ // Removes and duplicate /s (e.g. file:///a//b/c)
+ Uri resolvedUri = Uri.fromFile(f);
+ String rootUriNoTrailingSlash = rootUri.getEncodedPath();
+ rootUriNoTrailingSlash = rootUriNoTrailingSlash.substring(0, rootUriNoTrailingSlash.length() - 1);
+ if (!resolvedUri.getEncodedPath().startsWith(rootUriNoTrailingSlash)) {
+ return null;
+ }
+ String subPath = resolvedUri.getEncodedPath().substring(rootUriNoTrailingSlash.length());
+ // Strip leading slash
+ if (!subPath.isEmpty()) {
+ subPath = subPath.substring(1);
+ }
+ Uri.Builder b = new Uri.Builder()
+ .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL)
+ .authority("localhost")
+ .path(name);
+ if (!subPath.isEmpty()) {
+ b.appendEncodedPath(subPath);
+ }
+ if (f.isDirectory() || inputURL.getPath().endsWith("/")) {
+ // Add trailing / for directories.
+ b.appendEncodedPath("");
+ }
+ return LocalFilesystemURL.parse(b.build());
+ }
@Override
public LocalFilesystemURL URLforFilesystemPath(String path) {
return this.URLforFullPath(this.fullPathForFilesystemPath(path));
}
+ /**
+ * Removes multiple repeated //s, and collapses processes ../s.
+ */
protected String normalizePath(String rawPath) {
// If this is an absolute path, trim the leading "/" and replace it later
boolean isAbsolutePath = rawPath.startsWith("/");
if (isAbsolutePath) {
- rawPath = rawPath.substring(1);
+ rawPath = rawPath.replaceFirst("/+", "");
}
ArrayList<String> components = new ArrayList<String>(Arrays.asList(rawPath.split("/+")));
for (int index = 0; index < components.size(); ++index) {
@@ -120,18 +157,12 @@ public class LocalFilesystem extends Filesystem {
} else {
return normalizedPath.toString().substring(1);
}
-
-
}
@Override
- public JSONObject makeEntryForFile(File file) throws JSONException {
- String path = this.fullPathForFilesystemPath(file.getAbsolutePath());
- if (path != null) {
- return makeEntryForPath(path, this.name, file.isDirectory(), Uri.fromFile(file).toString());
- }
- return null;
+ public JSONObject makeEntryForFile(File file) {
+ return makeEntryForNativeUri(Uri.fromFile(file));
}
@Override
@@ -144,7 +175,7 @@ public class LocalFilesystem extends Filesystem {
if (!fp.canRead()) {
throw new IOException();
}
- return LocalFilesystem.makeEntryForURL(inputURL, fp.isDirectory(), Uri.fromFile(fp));
+ return super.getEntryForLocalURL(inputURL);
}
@Override
@@ -168,10 +199,13 @@ public class LocalFilesystem extends Filesystem {
LocalFilesystemURL requestedURL;
// Check whether the supplied path is absolute or relative
+ if (directory && !path.endsWith("/")) {
+ path += "/";
+ }
if (path.startsWith("/")) {
- requestedURL = URLforFilesystemPath(path);
+ requestedURL = URLforFilesystemPath(normalizePath(path));
} else {
- requestedURL = URLforFullPath(normalizePath(inputURL.pathAndQuery + "/" + path));
+ requestedURL = URLforFullPath(normalizePath(inputURL.path + "/" + path));
}
File fp = new File(this.filesystemPathForURL(requestedURL));
@@ -205,7 +239,7 @@ public class LocalFilesystem extends Filesystem {
}
// Return the directory
- return makeEntryForPath(requestedURL.pathAndQuery, requestedURL.fsName, directory, Uri.fromFile(fp).toString());
+ return makeEntryForURL(requestedURL);
}
@Override
@@ -256,7 +290,7 @@ public class LocalFilesystem extends Filesystem {
File[] files = fp.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].canRead()) {
- entries.put(makeEntryForPath(fullPathForFilesystemPath(files[i].getAbsolutePath()), inputURL.fsName, files[i].isDirectory(), Uri.fromFile(files[i]).toString()));
+ entries.put(makeEntryForFile(files[i]));
}
}
}
@@ -278,7 +312,7 @@ public class LocalFilesystem extends Filesystem {
metadata.put("size", file.isDirectory() ? 0 : file.length());
metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file)));
metadata.put("name", file.getName());
- metadata.put("fullPath", inputURL.pathAndQuery);
+ metadata.put("fullPath", inputURL.path);
metadata.put("lastModifiedDate", file.lastModified());
} catch (JSONException e) {
return null;
@@ -514,30 +548,6 @@ public class LocalFilesystem extends Filesystem {
return super.copyFileToURL(destURL, newName, srcFs, srcURL, move);
}
}
-
- @Override
- public void readFileAtURL(LocalFilesystemURL inputURL, long start, long end,
- ReadFileCallback readFileCallback) throws IOException {
-
- File file = new File(this.filesystemPathForURL(inputURL));
- String contentType = resourceApi.getMimeType(Uri.fromFile(file));
-
- if (end < 0) {
- end = file.length();
- }
- long numBytesToRead = end - start;
-
- InputStream rawInputStream = new FileInputStream(file);
- try {
- if (start > 0) {
- rawInputStream.skip(start);
- }
- LimitedInputStream inputStream = new LimitedInputStream(rawInputStream, numBytesToRead);
- readFileCallback.handleData(inputStream, contentType);
- } finally {
- rawInputStream.close();
- }
- }
@Override
public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
@@ -624,13 +634,4 @@ public class LocalFilesystem extends Filesystem {
File file = new File(path);
return file.exists();
}
-
- @Override
- OutputStream getOutputStreamForURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
- String path = filesystemPathForURL(inputURL);
- File file = new File(path);
- FileOutputStream os = new FileOutputStream(file);
- return os;
- }
-
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/src/android/LocalFilesystemURL.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystemURL.java b/src/android/LocalFilesystemURL.java
index 473b587..b96b6ee 100644
--- a/src/android/LocalFilesystemURL.java
+++ b/src/android/LocalFilesystemURL.java
@@ -18,8 +18,6 @@
*/
package org.apache.cordova.file;
-import java.util.List;
-
import android.net.Uri;
public class LocalFilesystemURL {
@@ -28,29 +26,32 @@ public class LocalFilesystemURL {
public final Uri uri;
public final String fsName;
- public final String pathAndQuery;
+ public final String path;
+ public final boolean isDirectory;
- private LocalFilesystemURL(Uri uri, String fsName, String fsPath) {
+ private LocalFilesystemURL(Uri uri, String fsName, String fsPath, boolean isDirectory) {
this.uri = uri;
this.fsName = fsName;
- this.pathAndQuery = fsPath;
+ this.path = fsPath;
+ this.isDirectory = isDirectory;
}
public static LocalFilesystemURL parse(Uri uri) {
if (!FILESYSTEM_PROTOCOL.equals(uri.getScheme())) {
return null;
}
- List<String> pathComponents = uri.getPathSegments();
- if (pathComponents == null || pathComponents.size() == 0) {
+ String path = uri.getPath();
+ if (path.length() < 1) {
return null;
}
- String fsName = pathComponents.get(0);
- String pathAndQuery = uri.getPath();
- pathAndQuery = pathAndQuery.substring(pathAndQuery.indexOf('/', 1));
- if (uri.getQuery() != null) {
- pathAndQuery = pathAndQuery + "?" + uri.getQuery();
+ int firstSlashIdx = path.indexOf('/', 1);
+ if (firstSlashIdx < 0) {
+ return null;
}
- return new LocalFilesystemURL(uri, fsName, pathAndQuery);
+ String fsName = path.substring(1, firstSlashIdx);
+ path = path.substring(firstSlashIdx);
+ boolean isDirectory = path.charAt(path.length() - 1) == '/';
+ return new LocalFilesystemURL(uri, fsName, path, isDirectory);
}
public static LocalFilesystemURL parse(String uri) {
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/tests/plugin.xml
----------------------------------------------------------------------
diff --git a/tests/plugin.xml b/tests/plugin.xml
index ba1b01c..80adb4e 100644
--- a/tests/plugin.xml
+++ b/tests/plugin.xml
@@ -29,4 +29,14 @@
<js-module src="tests.js" name="tests">
</js-module>
+
+ <platform name="android">
+ <source-file src="src/android/TestContentProvider.java" target-dir="src/org/apache/cordova/file/test" />
+ <config-file target="AndroidManifest.xml" parent="/*/application">
+ <provider
+ android:name="org.apache.cordova.file.test.TestContentProvider"
+ android:authorities="org.apache.cordova.file.testprovider"
+ android:exported="false" />
+ </config-file>
+ </platform>
</plugin>
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/tests/src/android/TestContentProvider.java
----------------------------------------------------------------------
diff --git a/tests/src/android/TestContentProvider.java b/tests/src/android/TestContentProvider.java
new file mode 100644
index 0000000..1aa4783
--- /dev/null
+++ b/tests/src/android/TestContentProvider.java
@@ -0,0 +1,78 @@
+package org.apache.cordova.file.test;
+
+import android.content.ContentProvider;
+import android.net.Uri;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.os.ParcelFileDescriptor;
+
+import org.apache.cordova.CordovaResourceApi;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+public class TestContentProvider extends ContentProvider {
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ String fileName = uri.getQueryParameter("realPath");
+ if (fileName == null) {
+ fileName = uri.getPath();
+ }
+ if (fileName == null || fileName.length() < 1) {
+ throw new FileNotFoundException();
+ }
+ CordovaResourceApi resourceApi = new CordovaResourceApi(getContext(), null);
+ try {
+ File f = File.createTempFile("test-content-provider", ".tmp");
+ resourceApi.copyResource(Uri.parse("file:///android_asset" + fileName), Uri.fromFile(f));
+ FileInputStream fis = new FileInputStream(f);
+ String thisIsDumb = fis.getFD().toString();
+ int fd = Integer.parseInt(thisIsDumb.substring("FileDescriptor[".length(), thisIsDumb.length() - 1));
+ return ParcelFileDescriptor.adoptFd(fd);
+ } catch (FileNotFoundException e) {
+ throw e;
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new FileNotFoundException("IO error: " + e.toString());
+ }
+ }
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return "text/html";
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/tests/tests.js
----------------------------------------------------------------------
diff --git a/tests/tests.js b/tests/tests.js
index 1478aaf..adaa9ab 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -2090,8 +2090,7 @@ exports.defineAutoTests = function () {
expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
}
// cleanup
- deleteEntry(file1);
- done();
+ deleteEntry(file1, done);
});
}, failed.bind(null, done, 'createFile - Error creating file: ' + file1));
});
@@ -2904,8 +2903,7 @@ exports.defineAutoTests = function () {
expect(fileEntry.name).toBe(fileName);
expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath +'/' + fileName);
// cleanup
- deleteEntry(fileName);
- done();
+ deleteEntry(fileName, done);
}, failed.bind(null, done, 'root.getFile - Error getting file: ../' + fileName));
}, failed.bind(null, done, 'createFile - Error creating file: ../' + fileName));
});
@@ -3131,8 +3129,7 @@ exports.defineAutoTests = function () {
: expect(entry.filesystem.name).toEqual("persistent");
// cleanup
deleteEntry(entry.name);
- deleteEntry(sourceEntry.name);
- done();
+ deleteEntry(sourceEntry.name, done);
},
createSourceAndTransfer = function () {
temp_root.getFile(file1, {
@@ -3166,8 +3163,7 @@ exports.defineAutoTests = function () {
: expect(entry.filesystem.name).toEqual("temporary");
// cleanup
deleteEntry(entry.name);
- deleteEntry(sourceEntry.name);
- done();
+ deleteEntry(sourceEntry.name, done);
},
createSourceAndTransfer = function () {
persistent_root.getFile(file1, {
@@ -3204,8 +3200,7 @@ exports.defineAutoTests = function () {
: expect(entry.filesystem.name).toEqual("persistent");
// cleanup
deleteEntry(entry.name);
- deleteEntry(sourceEntry.name);
- done();
+ deleteEntry(sourceEntry.name, done);
},
createSourceAndTransfer = function () {
temp_root.getFile(file1, {
@@ -3239,8 +3234,7 @@ exports.defineAutoTests = function () {
: expect(entry.filesystem.name).toEqual("temporary");
// cleanup
deleteEntry(entry.name);
- deleteEntry(sourceEntry.name);
- done();
+ deleteEntry(sourceEntry.name, done);
},
createSourceAndTransfer = function () {
persistent_root.getFile(file1, {
@@ -3314,8 +3308,7 @@ exports.defineAutoTests = function () {
expect(directory.name).toCanonicallyMatch(nestedName);
expect(directory.fullPath).toCanonicallyMatch('/' + path + '/');
deleteEntry(directory.name);
- deleteEntry(parentName);
- done();
+ deleteEntry(parentName, done);
};
createDirectory(parentName, function() {
@@ -3334,8 +3327,7 @@ exports.defineAutoTests = function () {
expect(fileEntry.isFile).toBe(true);
expect(fileEntry.isDirectory).toBe(false);
expect(fileEntry.name).toCanonicallyMatch(secondFileName);
- deleteEntry(fileEntry.name);
- done();
+ deleteEntry(fileEntry.name, done);
};
createFile(deletedFileName, function (deletedFile) {
@@ -3359,8 +3351,7 @@ exports.defineAutoTests = function () {
expect(directory.isFile).toBe(false);
expect(directory.isDirectory).toBe(true);
expect(directory.name).toCanonicallyMatch(secondDirName);
- deleteEntry(directory.name);
- done();
+ deleteEntry(directory.name, done);
};
createDirectory(deletedDirName, function (deletedDir) {
@@ -3383,8 +3374,7 @@ exports.defineAutoTests = function () {
expect(directory.isFile).toBe(false);
expect(directory.isDirectory).toBe(true);
expect(directory.name).toCanonicallyMatch(parentName);
- deleteEntry(directory.name);
- done();
+ deleteEntry(directory.name, done);
};
createDirectory(parentName, function(parent){
@@ -3405,8 +3395,7 @@ exports.defineAutoTests = function () {
expect(directory.isFile).toBe(false);
expect(directory.isDirectory).toBe(true);
expect(directory.name).toCanonicallyMatch(dirName);
- deleteEntry(directory.name);
- done();
+ deleteEntry(directory.name, done);
};
createDirectory(dirName, function(){
@@ -3415,9 +3404,47 @@ exports.defineAutoTests = function () {
}, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + dirName));
});
});
- // IndexedDB-based impl
+ // Content and Asset URLs
+ if (cordova.platformId == 'android') {
+ describe('content: URLs', function() {
+ function testContentCopy(src, done) {
+ var file2 = "entry.copy.file2b",
+ fullPath = joinURL(temp_root.fullPath, file2),
+ validateFile = function (entry) {
+ expect(entry.isFile).toBe(true);
+ expect(entry.isDirectory).toBe(false);
+ expect(entry.name).toCanonicallyMatch(file2);
+ expect(entry.fullPath).toCanonicallyMatch(fullPath);
+ expect(entry.filesystem.name).toEqual("temporary");
+ // cleanup
+ deleteEntry(entry.name, done);
+ },
+ transfer = function () {
+ resolveLocalFileSystemURL(src, function(entry) {
+ expect(entry).toBeDefined();
+ expect(entry.filesystem.name).toEqual("content");
+ entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + entry.toURL() + ' to TEMPORAL root as: ' + file2));
+ }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider'));
+ };
+ // Delete any existing file to start things off
+ temp_root.getFile(file2, {}, function (entry) {
+ entry.remove(transfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));
+ }, transfer);
+ }
+ it("file.spec.138 copyTo: content", function(done) {
+ testContentCopy('content://org.apache.cordova.file.testprovider/www/index.html', done);
+ });
+ it("file.spec.139 copyTo: content /w space and query", function(done) {
+ testContentCopy('content://org.apache.cordova.file.testprovider/?name=foo%20bar&realPath=%2Fwww%2Findex.html', done);
+ });
+ it("file.spec.140 delete: content should fail", function(done) {
+ resolveLocalFileSystemURL('content://org.apache.cordova.file.testprovider/www/index.html', function(entry) {
+ entry.remove(failed.bind(null, done, 'expected delete to fail'), done);
+ }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider'));
+ });
+ });
+ }
});
- //File API describe
};
//******************************************************************************************
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/www/Entry.js
----------------------------------------------------------------------
diff --git a/www/Entry.js b/www/Entry.js
index 12f6227..c23f8e2 100644
--- a/www/Entry.js
+++ b/www/Entry.js
@@ -180,7 +180,7 @@ Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallbac
*/
Entry.prototype.toInternalURL = function() {
if (this.filesystem && this.filesystem.__format__) {
- return this.filesystem.__format__(this.fullPath);
+ return this.filesystem.__format__(this.fullPath, this.nativeURL);
}
};
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/www/FileSystem.js
----------------------------------------------------------------------
diff --git a/www/FileSystem.js b/www/FileSystem.js
index efa6740..36bffbb 100644
--- a/www/FileSystem.js
+++ b/www/FileSystem.js
@@ -37,7 +37,7 @@ var FileSystem = function(name, root) {
}
};
-FileSystem.prototype.__format__ = function(fullPath) {
+FileSystem.prototype.__format__ = function(fullPath, nativeUrl) {
return fullPath;
};
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/d6202261/www/android/FileSystem.js
----------------------------------------------------------------------
diff --git a/www/android/FileSystem.js b/www/android/FileSystem.js
index fde9c7a..518e4c4 100644
--- a/www/android/FileSystem.js
+++ b/www/android/FileSystem.js
@@ -22,12 +22,15 @@
FILESYSTEM_PROTOCOL = "cdvfile";
module.exports = {
- __format__: function(fullPath) {
- if (this.name === 'content') {
- return 'content:/' + fullPath;
+ __format__: function(fullPath, nativeUrl) {
+ var path = '/' + this.name + '/' + encodeURI(fullPath);
+ path = path.replace('//','/');
+ var ret = FILESYSTEM_PROTOCOL + '://localhost' + path;
+ var m = /\?.*/.exec(nativeUrl);
+ if (m) {
+ ret += m[0];
}
- var path = ('/'+this.name+(fullPath[0]==='/'?'':'/')+encodeURI(fullPath)).replace('//','/');
- return FILESYSTEM_PROTOCOL + '://localhost' + path;
+ return ret;
}
};
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[07/13] cordova-plugin-file git commit: android: Move
CordovaResourceApi into Filesystem base class
Posted by ag...@apache.org.
android: Move CordovaResourceApi into Filesystem base class
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/bad4242a
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/bad4242a
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/bad4242a
Branch: refs/heads/master
Commit: bad4242a304ad883144856417d81d972669a42ba
Parents: 81ea13c
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Mar 9 14:22:04 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
src/android/ContentFilesystem.java | 33 +++++++--------------------------
src/android/FileUtils.java | 2 +-
src/android/Filesystem.java | 5 ++++-
src/android/LocalFilesystem.java | 5 +----
4 files changed, 13 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/bad4242a/src/android/ContentFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java
index f577054..3e967f3 100644
--- a/src/android/ContentFilesystem.java
+++ b/src/android/ContentFilesystem.java
@@ -36,6 +36,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.content.ContentResolver;
+import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
@@ -43,31 +44,11 @@ import android.provider.OpenableColumns;
public class ContentFilesystem extends Filesystem {
- private CordovaInterface cordova;
- private CordovaResourceApi resourceApi;
-
- public ContentFilesystem(CordovaInterface cordova, CordovaWebView webView) {
- super(Uri.parse("content://"), "content");
- this.cordova = cordova;
+ private final Context context;
- Class webViewClass = webView.getClass();
- PluginManager pm = null;
- try {
- Method gpm = webViewClass.getMethod("getPluginManager");
- pm = (PluginManager) gpm.invoke(webView);
- } catch (NoSuchMethodException e) {
- } catch (IllegalAccessException e) {
- } catch (InvocationTargetException e) {
- }
- if (pm == null) {
- try {
- Field pmf = webViewClass.getField("pluginManager");
- pm = (PluginManager)pmf.get(webView);
- } catch (NoSuchFieldException e) {
- } catch (IllegalAccessException e) {
- }
- }
- this.resourceApi = new CordovaResourceApi(webView.getContext(), pm);
+ public ContentFilesystem(Context context, CordovaResourceApi resourceApi) {
+ super(Uri.parse("content://"), "content", resourceApi);
+ this.context = context;
}
@Override
@@ -130,7 +111,7 @@ public class ContentFilesystem extends Filesystem {
String filePath = filesystemPathForURL(inputURL);
File file = new File(filePath);
try {
- this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ context.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaStore.Images.Media.DATA + " = ?",
new String[] { filePath });
} catch (UnsupportedOperationException t) {
@@ -246,7 +227,7 @@ public class ContentFilesystem extends Filesystem {
}
protected Cursor openCursorForURL(LocalFilesystemURL url) {
- ContentResolver contentResolver = this.cordova.getActivity().getContentResolver();
+ ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(url.URL, null, null, null, null);
return cursor;
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/bad4242a/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index 0063b43..043bdca 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -194,7 +194,7 @@ public class FileUtils extends CordovaPlugin {
// per spec.
this.registerFilesystem(new LocalFilesystem("temporary", webView.getContext(), webView.getResourceApi(), tempRoot));
this.registerFilesystem(new LocalFilesystem("persistent", webView.getContext(), webView.getResourceApi(), persistentRoot));
- this.registerFilesystem(new ContentFilesystem(cordova, webView));
+ this.registerFilesystem(new ContentFilesystem(webView.getContext(), webView.getResourceApi()));
registerExtraFileSystems(getExtraFileSystemsPreference(activity), getAvailableFileSystems(activity));
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/bad4242a/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index c4a0f8a..d1cbc27 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -27,6 +27,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import org.apache.cordova.CordovaResourceApi;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -34,12 +35,14 @@ import org.json.JSONObject;
public abstract class Filesystem {
protected final Uri rootUri;
+ protected final CordovaResourceApi resourceApi;
public final String name;
private final JSONObject rootEntry;
- public Filesystem(Uri rootUri, String name) {
+ public Filesystem(Uri rootUri, String name, CordovaResourceApi resourceApi) {
this.rootUri = rootUri;
this.name = name;
+ this.resourceApi = resourceApi;
rootEntry = makeEntryForPath("/", name, true, rootUri.toString());
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/bad4242a/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 884771c..544663d 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -44,17 +44,14 @@ import android.content.Intent;
import android.app.Activity;
public class LocalFilesystem extends Filesystem {
-
- private final CordovaResourceApi resourceApi;
private final Context context;
public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, String rootPath) {
this(name, context, resourceApi, Uri.fromFile(new File(rootPath)));
}
public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, Uri rootUri) {
- super(rootUri, name);
+ super(rootUri, name, resourceApi);
this.context = context;
- this.resourceApi = resourceApi;
}
public String filesystemPathForFullPath(String fullPath) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[03/13] cordova-plugin-file git commit: android: Ensure
LocalFilesystemURL can only be created with "cdvfile" URLs
Posted by ag...@apache.org.
android: Ensure LocalFilesystemURL can only be created with "cdvfile" URLs
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/8f7b013b
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/8f7b013b
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/8f7b013b
Branch: refs/heads/master
Commit: 8f7b013baad2545eb7ed83e12ad924d354c5f1b2
Parents: bad4242
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Mar 9 14:44:32 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
src/android/ContentFilesystem.java | 48 +++++++++-------------
src/android/FileUtils.java | 38 +++++++++---------
src/android/Filesystem.java | 22 +++++-----
src/android/LocalFilesystem.java | 20 ++++-----
src/android/LocalFilesystemURL.java | 69 ++++++++++++++------------------
5 files changed, 88 insertions(+), 109 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/8f7b013b/src/android/ContentFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java
index 3e967f3..a4a2227 100644
--- a/src/android/ContentFilesystem.java
+++ b/src/android/ContentFilesystem.java
@@ -53,28 +53,20 @@ public class ContentFilesystem extends Filesystem {
@Override
public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {
- if ("/".equals(inputURL.fullPath)) {
- return LocalFilesystem.makeEntryForURL(inputURL, true, inputURL.URL.toString());
+ if ("/".equals(inputURL.uri.getPath())) {
+ return LocalFilesystem.makeEntryForURL(inputURL, true, inputURL.uri);
}
// Get the cursor to validate that the file exists
Cursor cursor = openCursorForURL(inputURL);
- String filePath = null;
- try {
- if (cursor == null || !cursor.moveToFirst()) {
- throw new FileNotFoundException();
- }
- filePath = filesystemPathForCursor(cursor);
- } finally {
- if (cursor != null)
- cursor.close();
- }
- if (filePath == null) {
- filePath = inputURL.URL.toString();
+ File file = resourceApi.mapUriToFile(inputURL.uri);
+ Uri nativeUrl;
+ if (file == null) {
+ nativeUrl = inputURL.uri;
} else {
- filePath = "file://" + filePath;
+ nativeUrl = Uri.fromFile(file);
}
- return makeEntryForPath(inputURL.fullPath, inputURL.filesystemName, false /*fp.isDirectory()*/, filePath);
+ return makeEntryForURL(inputURL, false /*fp.isDirectory()*/, nativeUrl);
}
@Override
@@ -85,7 +77,7 @@ public class ContentFilesystem extends Filesystem {
throw new IOException("Cannot create content url");
}
}
- LocalFilesystemURL requestedURL = new LocalFilesystemURL(Uri.withAppendedPath(inputURL.URL, fileName));
+ LocalFilesystemURL requestedURL = LocalFilesystemURL.parse(Uri.withAppendedPath(inputURL.uri, fileName));
File fp = new File(this.filesystemPathForURL(requestedURL));
if (!fp.exists()) {
throw new FileNotFoundException("path does not exist");
@@ -100,7 +92,7 @@ public class ContentFilesystem extends Filesystem {
}
}
// Return the directory
- return makeEntryForPath(requestedURL.fullPath, requestedURL.filesystemName, directory, Uri.fromFile(fp).toString());
+ return makeEntryForURL(requestedURL, directory, Uri.fromFile(fp));
}
@@ -155,9 +147,9 @@ public class ContentFilesystem extends Filesystem {
JSONObject metadata = new JSONObject();
try {
metadata.put("size", size);
- metadata.put("type", resourceApi.getMimeType(inputURL.URL));
- metadata.put("name", inputURL.filesystemName);
- metadata.put("fullPath", inputURL.fullPath);
+ metadata.put("type", resourceApi.getMimeType(inputURL.uri));
+ metadata.put("name", name);
+ metadata.put("fullPath", inputURL.pathAndQuery);
metadata.put("lastModifiedDate", lastModified);
} catch (JSONException e) {
return null;
@@ -175,8 +167,8 @@ public class ContentFilesystem extends Filesystem {
// Figure out where we should be copying to
final LocalFilesystemURL destinationURL = makeDestinationURL(newName, srcURL, destURL);
- OutputStream os = resourceApi.openOutputStream(destURL.URL);
- CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(srcURL.URL);
+ OutputStream os = resourceApi.openOutputStream(destURL.uri);
+ CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(srcURL.uri);
if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {
throw new NoModificationAllowedException("Cannot move file at source URL");
}
@@ -188,7 +180,7 @@ public class ContentFilesystem extends Filesystem {
if (move) {
srcFs.removeFileAtLocalURL(srcURL);
}
- return makeEntryForURL(destinationURL, false, destinationURL.URL.toString());
+ return makeEntryForURL(destinationURL, false, destinationURL.uri);
} else {
// Need to copy the hard way
return super.copyFileToURL(destURL, newName, srcFs, srcURL, move);
@@ -199,7 +191,7 @@ public class ContentFilesystem extends Filesystem {
@Override
public void readFileAtURL(LocalFilesystemURL inputURL, long start, long end,
ReadFileCallback readFileCallback) throws IOException {
- CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(inputURL.URL);
+ CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(inputURL.uri);
if (end < 0) {
end = ofrr.length;
}
@@ -228,7 +220,7 @@ public class ContentFilesystem extends Filesystem {
protected Cursor openCursorForURL(LocalFilesystemURL url) {
ContentResolver contentResolver = context.getContentResolver();
- Cursor cursor = contentResolver.query(url.URL, null, null, null, null);
+ Cursor cursor = contentResolver.query(url.uri, null, null, null, null);
return cursor;
}
@@ -257,7 +249,7 @@ public class ContentFilesystem extends Filesystem {
@Override
public String filesystemPathForURL(LocalFilesystemURL url) {
- File f = resourceApi.mapUriToFile(url.URL);
+ File f = resourceApi.mapUriToFile(url.uri);
return f == null ? null : f.getAbsolutePath();
}
@@ -277,7 +269,7 @@ public class ContentFilesystem extends Filesystem {
@Override
OutputStream getOutputStreamForURL(LocalFilesystemURL inputURL)
throws IOException {
- OutputStream os = resourceApi.openOutputStream(inputURL.URL);
+ OutputStream os = resourceApi.openOutputStream(inputURL.uri);
return os;
}
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/8f7b013b/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index 043bdca..2a1e965 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -214,7 +214,7 @@ public class FileUtils extends CordovaPlugin {
private Filesystem filesystemForURL(LocalFilesystemURL localURL) {
if (localURL == null) return null;
- return filesystemForName(localURL.filesystemName);
+ return filesystemForName(localURL.fsName);
}
@Override
@@ -224,7 +224,7 @@ public class FileUtils extends CordovaPlugin {
return null;
}
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(uri);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
return null;
@@ -511,7 +511,7 @@ public class FileUtils extends CordovaPlugin {
public String filesystemPathForURL(String localURLstr) throws MalformedURLException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(localURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(localURLstr);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
@@ -534,9 +534,9 @@ public class FileUtils extends CordovaPlugin {
if (url != null) {
// A shorter fullPath implies that the filesystem is a better
// match for the local path than the previous best.
- if (localURL == null || (url.fullPath.length() < shortestFullPath)) {
+ if (localURL == null || (url.pathAndQuery.length() < shortestFullPath)) {
localURL = url;
- shortestFullPath = url.fullPath.length();
+ shortestFullPath = url.pathAndQuery.length();
}
}
}
@@ -603,7 +603,7 @@ public class FileUtils extends CordovaPlugin {
String path = uri.getPath();
inputURL = this.filesystemURLforLocalPath(path);
} else {
- inputURL = new LocalFilesystemURL(uri);
+ inputURL = LocalFilesystemURL.parse(uri);
}
try {
@@ -627,7 +627,7 @@ public class FileUtils extends CordovaPlugin {
*/
private JSONArray readEntries(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
@@ -658,8 +658,8 @@ public class FileUtils extends CordovaPlugin {
throw new FileNotFoundException();
}
- LocalFilesystemURL srcURL = new LocalFilesystemURL(srcURLstr);
- LocalFilesystemURL destURL = new LocalFilesystemURL(destURLstr);
+ LocalFilesystemURL srcURL = LocalFilesystemURL.parse(srcURLstr);
+ LocalFilesystemURL destURL = LocalFilesystemURL.parse(destURLstr);
Filesystem srcFs = this.filesystemForURL(srcURL);
Filesystem destFs = this.filesystemForURL(destURL);
@@ -685,9 +685,9 @@ public class FileUtils extends CordovaPlugin {
*/
private boolean removeRecursively(String baseURLstr) throws FileExistsException, NoModificationAllowedException, MalformedURLException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
// You can't delete the root directory.
- if ("".equals(inputURL.fullPath) || "/".equals(inputURL.fullPath)) {
+ if ("".equals(inputURL.pathAndQuery) || "/".equals(inputURL.pathAndQuery)) {
throw new NoModificationAllowedException("You can't delete the root directory");
}
@@ -714,9 +714,9 @@ public class FileUtils extends CordovaPlugin {
*/
private boolean remove(String baseURLstr) throws NoModificationAllowedException, InvalidModificationException, MalformedURLException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
// You can't delete the root directory.
- if ("".equals(inputURL.fullPath) || "/".equals(inputURL.fullPath)) {
+ if ("".equals(inputURL.pathAndQuery) || "/".equals(inputURL.pathAndQuery)) {
throw new NoModificationAllowedException("You can't delete the root directory");
}
@@ -748,7 +748,7 @@ public class FileUtils extends CordovaPlugin {
*/
private JSONObject getFile(String baseURLstr, String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
@@ -767,7 +767,7 @@ public class FileUtils extends CordovaPlugin {
*/
private JSONObject getParent(String baseURLstr) throws JSONException, IOException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
@@ -786,7 +786,7 @@ public class FileUtils extends CordovaPlugin {
*/
private JSONObject getFileMetadata(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(baseURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
@@ -913,7 +913,7 @@ public class FileUtils extends CordovaPlugin {
*/
public void readFileAs(final String srcURLstr, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) throws MalformedURLException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(srcURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
@@ -982,7 +982,7 @@ public class FileUtils extends CordovaPlugin {
/**/
public long write(String srcURLstr, String data, int offset, boolean isBinary) throws FileNotFoundException, IOException, NoModificationAllowedException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(srcURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
@@ -1000,7 +1000,7 @@ public class FileUtils extends CordovaPlugin {
*/
private long truncateFile(String srcURLstr, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
try {
- LocalFilesystemURL inputURL = new LocalFilesystemURL(srcURLstr);
+ LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);
Filesystem fs = this.filesystemForURL(inputURL);
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/8f7b013b/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index d1cbc27..64b78b8 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -78,8 +78,8 @@ public abstract class Filesystem {
}
}
- public static JSONObject makeEntryForURL(LocalFilesystemURL inputURL, Boolean isDir, String nativeURL) {
- return makeEntryForPath(inputURL.fullPath, inputURL.filesystemName, isDir, nativeURL);
+ public static JSONObject makeEntryForURL(LocalFilesystemURL inputURL, Boolean isDir, Uri nativeURL) {
+ return makeEntryForPath(inputURL.pathAndQuery, inputURL.fsName, isDir, nativeURL.toString());
}
abstract JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException;
@@ -104,29 +104,27 @@ public abstract class Filesystem {
}
public JSONObject getParentForLocalURL(LocalFilesystemURL inputURL) throws IOException {
- LocalFilesystemURL newURL = new LocalFilesystemURL(inputURL.URL);
-
- if (!("".equals(inputURL.fullPath) || "/".equals(inputURL.fullPath))) {
- String dirURL = inputURL.fullPath.replaceAll("/+$", "");
- int lastPathStartsAt = dirURL.lastIndexOf('/')+1;
- newURL.fullPath = newURL.fullPath.substring(0,lastPathStartsAt);
+ Uri parentUri = inputURL.uri;
+ String parentPath = new File(inputURL.uri.getPath()).getParent();
+ if (!"/".equals(parentPath)) {
+ parentUri = inputURL.uri.buildUpon().path(parentPath + '/').build();
}
- return getEntryForLocalURL(newURL);
+ return getEntryForLocalURL(LocalFilesystemURL.parse(parentUri));
}
protected LocalFilesystemURL makeDestinationURL(String newName, LocalFilesystemURL srcURL, LocalFilesystemURL destURL) {
// I know this looks weird but it is to work around a JSON bug.
if ("null".equals(newName) || "".equals(newName)) {
- newName = srcURL.URL.getLastPathSegment();;
+ newName = srcURL.uri.getLastPathSegment();;
}
- String newDest = destURL.URL.toString();
+ String newDest = destURL.uri.toString();
if (newDest.endsWith("/")) {
newDest = newDest + newName;
} else {
newDest = newDest + "/" + newName;
}
- return new LocalFilesystemURL(newDest);
+ return LocalFilesystemURL.parse(newDest);
}
/* Read a source URL (possibly from a different filesystem, srcFs,) and copy it to
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/8f7b013b/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 544663d..805eacd 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -68,7 +68,7 @@ public class LocalFilesystem extends Filesystem {
@Override
public String filesystemPathForURL(LocalFilesystemURL url) {
- return filesystemPathForFullPath(url.fullPath);
+ return filesystemPathForFullPath(url.pathAndQuery);
}
private String fullPathForFilesystemPath(String absolutePath) {
@@ -81,9 +81,9 @@ public class LocalFilesystem extends Filesystem {
protected LocalFilesystemURL URLforFullPath(String fullPath) {
if (fullPath != null) {
if (fullPath.startsWith("/")) {
- return new LocalFilesystemURL(LocalFilesystemURL.FILESYSTEM_PROTOCOL + "://localhost/"+this.name+fullPath);
+ return LocalFilesystemURL.parse(LocalFilesystemURL.FILESYSTEM_PROTOCOL + "://localhost/"+this.name+fullPath);
}
- return new LocalFilesystemURL(LocalFilesystemURL.FILESYSTEM_PROTOCOL + "://localhost/"+this.name+"/"+fullPath);
+ return LocalFilesystemURL.parse(LocalFilesystemURL.FILESYSTEM_PROTOCOL + "://localhost/"+this.name+"/"+fullPath);
}
return null;
@@ -144,7 +144,7 @@ public class LocalFilesystem extends Filesystem {
if (!fp.canRead()) {
throw new IOException();
}
- return LocalFilesystem.makeEntryForURL(inputURL, fp.isDirectory(), Uri.fromFile(fp).toString());
+ return LocalFilesystem.makeEntryForURL(inputURL, fp.isDirectory(), Uri.fromFile(fp));
}
@Override
@@ -171,7 +171,7 @@ public class LocalFilesystem extends Filesystem {
if (path.startsWith("/")) {
requestedURL = URLforFilesystemPath(path);
} else {
- requestedURL = URLforFullPath(normalizePath(inputURL.fullPath + "/" + path));
+ requestedURL = URLforFullPath(normalizePath(inputURL.pathAndQuery + "/" + path));
}
File fp = new File(this.filesystemPathForURL(requestedURL));
@@ -205,7 +205,7 @@ public class LocalFilesystem extends Filesystem {
}
// Return the directory
- return makeEntryForPath(requestedURL.fullPath, requestedURL.filesystemName, directory, Uri.fromFile(fp).toString());
+ return makeEntryForPath(requestedURL.pathAndQuery, requestedURL.fsName, directory, Uri.fromFile(fp).toString());
}
@Override
@@ -256,7 +256,7 @@ public class LocalFilesystem extends Filesystem {
File[] files = fp.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].canRead()) {
- entries.put(makeEntryForPath(fullPathForFilesystemPath(files[i].getAbsolutePath()), inputURL.filesystemName, files[i].isDirectory(), Uri.fromFile(files[i]).toString()));
+ entries.put(makeEntryForPath(fullPathForFilesystemPath(files[i].getAbsolutePath()), inputURL.fsName, files[i].isDirectory(), Uri.fromFile(files[i]).toString()));
}
}
}
@@ -269,7 +269,7 @@ public class LocalFilesystem extends Filesystem {
File file = new File(filesystemPathForURL(inputURL));
if (!file.exists()) {
- throw new FileNotFoundException("File at " + inputURL.URL + " does not exist.");
+ throw new FileNotFoundException("File at " + inputURL.uri + " does not exist.");
}
JSONObject metadata = new JSONObject();
@@ -278,7 +278,7 @@ public class LocalFilesystem extends Filesystem {
metadata.put("size", file.isDirectory() ? 0 : file.length());
metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file)));
metadata.put("name", file.getName());
- metadata.put("fullPath", inputURL.fullPath);
+ metadata.put("fullPath", inputURL.pathAndQuery);
metadata.put("lastModifiedDate", file.lastModified());
} catch (JSONException e) {
return null;
@@ -599,7 +599,7 @@ public class LocalFilesystem extends Filesystem {
File file = new File(filesystemPathForURL(inputURL));
if (!file.exists()) {
- throw new FileNotFoundException("File at " + inputURL.URL + " does not exist.");
+ throw new FileNotFoundException("File at " + inputURL.uri + " does not exist.");
}
RandomAccessFile raf = new RandomAccessFile(filesystemPathForURL(inputURL), "rw");
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/8f7b013b/src/android/LocalFilesystemURL.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystemURL.java b/src/android/LocalFilesystemURL.java
index 2bf40c3..473b587 100644
--- a/src/android/LocalFilesystemURL.java
+++ b/src/android/LocalFilesystemURL.java
@@ -25,50 +25,39 @@ import android.net.Uri;
public class LocalFilesystemURL {
public static final String FILESYSTEM_PROTOCOL = "cdvfile";
-
- Uri URL;
- String filesystemName;
- String fullPath;
- public LocalFilesystemURL(Uri URL) {
- this.URL = URL;
- this.filesystemName = this.filesystemNameForLocalURL(URL);
- this.fullPath = this.fullPathForLocalURL(URL);
- }
-
- private String fullPathForLocalURL(Uri URL) {
- if (FILESYSTEM_PROTOCOL.equals(URL.getScheme()) && "localhost".equals(URL.getHost())) {
- String path = URL.getPath();
- if (URL.getQuery() != null) {
- path = path + "?" + URL.getQuery();
- }
- return path.substring(path.indexOf('/', 1));
- } else if ("content".equals(URL.getScheme())) {
- String path = '/' + URL.getHost() + URL.getPath();
- // Re-encode path component to handle Android 4.4+ Content URLs
- return Uri.encode(path,"/");
- }
- return null;
- }
+ public final Uri uri;
+ public final String fsName;
+ public final String pathAndQuery;
- private String filesystemNameForLocalURL(Uri URL) {
- if (FILESYSTEM_PROTOCOL.equals(URL.getScheme()) && "localhost".equals(URL.getHost())) {
- List<String> pathComponents = URL.getPathSegments();
- if (pathComponents != null && pathComponents.size() > 0) {
- return pathComponents.get(0);
- }
- return null;
- } else if ("content".equals(URL.getScheme())) {
- return "content";
- }
- return null;
+ private LocalFilesystemURL(Uri uri, String fsName, String fsPath) {
+ this.uri = uri;
+ this.fsName = fsName;
+ this.pathAndQuery = fsPath;
}
- public LocalFilesystemURL(String strURL) {
- this(Uri.parse(strURL));
- }
-
+ public static LocalFilesystemURL parse(Uri uri) {
+ if (!FILESYSTEM_PROTOCOL.equals(uri.getScheme())) {
+ return null;
+ }
+ List<String> pathComponents = uri.getPathSegments();
+ if (pathComponents == null || pathComponents.size() == 0) {
+ return null;
+ }
+ String fsName = pathComponents.get(0);
+ String pathAndQuery = uri.getPath();
+ pathAndQuery = pathAndQuery.substring(pathAndQuery.indexOf('/', 1));
+ if (uri.getQuery() != null) {
+ pathAndQuery = pathAndQuery + "?" + uri.getQuery();
+ }
+ return new LocalFilesystemURL(uri, fsName, pathAndQuery);
+ }
+
+ public static LocalFilesystemURL parse(String uri) {
+ return parse(Uri.parse(uri));
+ }
+
public String toString() {
- return "cdvfile://localhost/" + this.filesystemName + this.fullPath;
+ return uri.toString();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[12/13] cordova-plugin-file git commit: CB-6428 android: Add support
for file:///android_asset URLs
Posted by ag...@apache.org.
CB-6428 android: Add support for file:///android_asset URLs
Supports:
- listing
- copying of file
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/356d3343
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/356d3343
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/356d3343
Branch: refs/heads/master
Commit: 356d334382fe7f827b2635e0c3f819453f746bab
Parents: d620226
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Mar 10 16:25:23 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:08 2015 -0400
----------------------------------------------------------------------
plugin.xml | 1 +
src/android/AssetFilesystem.java | 222 ++++++++++++++++++++++++++++++++++
src/android/FileUtils.java | 6 +-
src/android/Filesystem.java | 74 ++++++++++--
src/android/LocalFilesystem.java | 72 ++---------
tests/tests.js | 37 ++++++
6 files changed, 337 insertions(+), 75 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/356d3343/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
index 10c0c65..c4b9dcf 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -129,6 +129,7 @@ xmlns:android="http://schemas.android.com/apk/res/android"
<source-file src="src/android/Filesystem.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/LocalFilesystem.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/ContentFilesystem.java" target-dir="src/org/apache/cordova/file" />
+ <source-file src="src/android/AssetFilesystem.java" target-dir="src/org/apache/cordova/file" />
<!-- android specific file apis -->
<js-module src="www/android/FileSystem.js" name="androidFileSystem">
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/356d3343/src/android/AssetFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/AssetFilesystem.java b/src/android/AssetFilesystem.java
new file mode 100644
index 0000000..7a54e43
--- /dev/null
+++ b/src/android/AssetFilesystem.java
@@ -0,0 +1,222 @@
+/*
+ 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.file;
+
+import android.content.res.AssetManager;
+import android.net.Uri;
+
+import org.apache.cordova.CordovaResourceApi;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class AssetFilesystem extends Filesystem {
+
+ private final AssetManager assetManager;
+
+ public AssetFilesystem(AssetManager assetManager, CordovaResourceApi resourceApi) {
+ super(Uri.parse("file:///android_asset/"), "assets", resourceApi);
+ this.assetManager = assetManager;
+ }
+
+ @Override
+ public Uri toNativeUri(LocalFilesystemURL inputURL) {
+ return nativeUriForFullPath(inputURL.path);
+ }
+
+ @Override
+ public LocalFilesystemURL toLocalUri(Uri inputURL) {
+ if (!"file".equals(inputURL.getScheme())) {
+ return null;
+ }
+ File f = new File(inputURL.getPath());
+ // Removes and duplicate /s (e.g. file:///a//b/c)
+ Uri resolvedUri = Uri.fromFile(f);
+ String rootUriNoTrailingSlash = rootUri.getEncodedPath();
+ rootUriNoTrailingSlash = rootUriNoTrailingSlash.substring(0, rootUriNoTrailingSlash.length() - 1);
+ if (!resolvedUri.getEncodedPath().startsWith(rootUriNoTrailingSlash)) {
+ return null;
+ }
+ String subPath = resolvedUri.getEncodedPath().substring(rootUriNoTrailingSlash.length());
+ // Strip leading slash
+ if (!subPath.isEmpty()) {
+ subPath = subPath.substring(1);
+ }
+ Uri.Builder b = new Uri.Builder()
+ .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL)
+ .authority("localhost")
+ .path(name);
+ if (!subPath.isEmpty()) {
+ b.appendEncodedPath(subPath);
+ }
+ if (isDirectory(subPath) || inputURL.getPath().endsWith("/")) {
+ // Add trailing / for directories.
+ b.appendEncodedPath("");
+ }
+ return LocalFilesystemURL.parse(b.build());
+ }
+
+ private Boolean isDirectory(String assetPath) {
+ if (assetPath.startsWith("/")) {
+ assetPath = assetPath.substring(1);
+ }
+ try {
+ return assetManager.list(assetPath).length != 0;
+ } catch (IOException e) {
+ }
+ return false;
+ }
+
+ private LocalFilesystemURL URLforFullPath(String fullPath) {
+ Uri nativeUri = nativeUriForFullPath(fullPath);
+ if (nativeUri != null) {
+ return toLocalUri(nativeUri);
+ }
+ return null;
+ }
+
+
+ @Override
+ public JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
+ String[] files;
+ String pathNoSlashes = inputURL.path.substring(1);
+ if (pathNoSlashes.endsWith("/")) {
+ pathNoSlashes = pathNoSlashes.substring(0, pathNoSlashes.length() - 1);
+ }
+
+ try {
+ files = assetManager.list(pathNoSlashes);
+ } catch (IOException e) {
+ throw new FileNotFoundException();
+ }
+
+ JSONArray entries = new JSONArray();
+ if (files != null) {
+ for (String file : files) {
+ Uri newNativeUri = nativeUriForFullPath(new File(inputURL.path, file).getPath());
+ entries.put(makeEntryForNativeUri(newNativeUri));
+ }
+ }
+
+ return entries;
+ }
+
+ @Override
+ public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
+ String path, JSONObject options, boolean directory)
+ throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
+ if (options != null && options.optBoolean("create")) {
+ throw new UnsupportedOperationException("Assets are read-only");
+ }
+
+ // Check whether the supplied path is absolute or relative
+ if (directory && !path.endsWith("/")) {
+ path += "/";
+ }
+
+ LocalFilesystemURL requestedURL;
+ if (path.startsWith("/")) {
+ requestedURL = URLforFullPath(normalizePath(path));
+ } else {
+ requestedURL = URLforFullPath(normalizePath(inputURL.path + "/" + path));
+ }
+
+ // Throws a FileNotFoundException if it doesn't exist.
+ getFileMetadataForLocalURL(requestedURL);
+
+ boolean isDir = isDirectory(requestedURL.path);
+ if (directory && !isDir) {
+ throw new TypeMismatchException("path doesn't exist or is file");
+ } else if (!directory && isDir) {
+ throw new TypeMismatchException("path doesn't exist or is directory");
+ }
+
+ // Return the directory
+ return makeEntryForURL(requestedURL);
+ }
+
+
+ @Override
+ public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
+ CordovaResourceApi.OpenForReadResult offr;
+ try {
+ offr = inputURL.isDirectory ? null : resourceApi.openForRead(toNativeUri(inputURL));
+ } catch (IOException e) {
+ throw new FileNotFoundException("File not found: " + inputURL);
+ }
+ JSONObject metadata = new JSONObject();
+ try {
+ metadata.put("size", inputURL.isDirectory ? 0 : offr.length);
+ metadata.put("type", inputURL.isDirectory ? "text/directory" : offr.mimeType);
+ metadata.put("name", new File(inputURL.path).getName());
+ metadata.put("fullPath", inputURL.path);
+ metadata.put("lastModifiedDate", 0);
+ } catch (JSONException e) {
+ return null;
+ } finally {
+ if (offr != null) {
+ try {
+ offr.inputStream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ return metadata;
+ }
+
+ @Override
+ public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
+ return false;
+ }
+
+ @Override
+ long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, boolean isBinary) throws NoModificationAllowedException, IOException {
+ throw new NoModificationAllowedException("Assets are read-only");
+ }
+
+ @Override
+ long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException, NoModificationAllowedException {
+ throw new NoModificationAllowedException("Assets are read-only");
+ }
+
+ @Override
+ String filesystemPathForURL(LocalFilesystemURL url) {
+ return null;
+ }
+
+ @Override
+ LocalFilesystemURL URLforFilesystemPath(String path) {
+ return null;
+ }
+
+ @Override
+ boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException {
+ throw new NoModificationAllowedException("Assets are read-only");
+ }
+
+ @Override
+ boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException {
+ throw new NoModificationAllowedException("Assets are read-only");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/356d3343/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index a810726..67ebbe1 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -194,6 +194,7 @@ public class FileUtils extends CordovaPlugin {
this.registerFilesystem(new LocalFilesystem("temporary", webView.getContext(), webView.getResourceApi(), tempRoot));
this.registerFilesystem(new LocalFilesystem("persistent", webView.getContext(), webView.getResourceApi(), persistentRoot));
this.registerFilesystem(new ContentFilesystem(webView.getContext(), webView.getResourceApi()));
+ this.registerFilesystem(new AssetFilesystem(webView.getContext().getAssets(), webView.getResourceApi()));
registerExtraFileSystems(getExtraFileSystemsPreference(activity), getAvailableFileSystems(activity));
@@ -623,10 +624,13 @@ public class FileUtils extends CordovaPlugin {
if (fs == null) {
throw new MalformedURLException("No installed handlers for this URL");
}
- return fs.getEntryForLocalURL(inputURL);
+ if (fs.exists(inputURL)) {
+ return fs.getEntryForLocalURL(inputURL);
+ }
} catch (IllegalArgumentException e) {
throw new MalformedURLException("Unrecognized filesystem URL");
}
+ throw new FileNotFoundException();
}
/**
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/356d3343/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index 2d64942..724976d 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -26,6 +26,8 @@ import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
import org.apache.cordova.CordovaResourceApi;
import org.json.JSONArray;
@@ -37,13 +39,12 @@ public abstract class Filesystem {
protected final Uri rootUri;
protected final CordovaResourceApi resourceApi;
public final String name;
- private final JSONObject rootEntry;
+ private JSONObject rootEntry;
public Filesystem(Uri rootUri, String name, CordovaResourceApi resourceApi) {
this.rootUri = rootUri;
this.name = name;
this.resourceApi = resourceApi;
- rootEntry = makeEntryForNativeUri(rootUri);
}
public interface ReadFileCallback {
@@ -94,6 +95,10 @@ public abstract class Filesystem {
return makeEntryForURL(inputURL);
}
+ public JSONObject makeEntryForFile(File file) {
+ return makeEntryForNativeUri(Uri.fromFile(file));
+ }
+
abstract JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, String path,
JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException;
@@ -109,10 +114,67 @@ public abstract class Filesystem {
return rootUri;
}
+ public boolean exists(LocalFilesystemURL inputURL) {
+ try {
+ getFileMetadataForLocalURL(inputURL);
+ } catch (FileNotFoundException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public Uri nativeUriForFullPath(String fullPath) {
+ Uri ret = null;
+ if (fullPath != null) {
+ String encodedPath = Uri.fromFile(new File(fullPath)).getEncodedPath();
+ if (encodedPath.startsWith("/")) {
+ encodedPath = encodedPath.substring(1);
+ }
+ ret = rootUri.buildUpon().appendEncodedPath(encodedPath).build();
+ }
+ return ret;
+ }
+
+ /**
+ * Removes multiple repeated //s, and collapses processes ../s.
+ */
+ protected static String normalizePath(String rawPath) {
+ // If this is an absolute path, trim the leading "/" and replace it later
+ boolean isAbsolutePath = rawPath.startsWith("/");
+ if (isAbsolutePath) {
+ rawPath = rawPath.replaceFirst("/+", "");
+ }
+ ArrayList<String> components = new ArrayList<String>(Arrays.asList(rawPath.split("/+")));
+ for (int index = 0; index < components.size(); ++index) {
+ if (components.get(index).equals("..")) {
+ components.remove(index);
+ if (index > 0) {
+ components.remove(index-1);
+ --index;
+ }
+ }
+ }
+ StringBuilder normalizedPath = new StringBuilder();
+ for(String component: components) {
+ normalizedPath.append("/");
+ normalizedPath.append(component);
+ }
+ if (isAbsolutePath) {
+ return normalizedPath.toString();
+ } else {
+ return normalizedPath.toString().substring(1);
+ }
+ }
+
+
+
public abstract Uri toNativeUri(LocalFilesystemURL inputURL);
public abstract LocalFilesystemURL toLocalUri(Uri inputURL);
public JSONObject getRootEntry() {
+ if (rootEntry == null) {
+ rootEntry = makeEntryForNativeUri(rootUri);
+ }
return rootEntry;
}
@@ -235,12 +297,4 @@ public abstract class Filesystem {
return numBytesRead;
}
}
-
- /* Create a FileEntry or DirectoryEntry given an actual file on device.
- * Return null if the file does not exist within this filesystem.
- */
- public JSONObject makeEntryForFile(File file) throws JSONException {
- return null;
- }
-
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/356d3343/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 2754b41..83c1384 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -66,18 +66,6 @@ public class LocalFilesystem extends Filesystem {
return null;
}
- private Uri nativeUriForFullPath(String fullPath) {
- Uri ret = null;
- if (fullPath != null) {
- String encodedPath = Uri.fromFile(new File(fullPath)).getEncodedPath();
- if (encodedPath.startsWith("/")) {
- encodedPath = encodedPath.substring(1);
- }
- ret = rootUri.buildUpon().appendEncodedPath(encodedPath).build();
- }
- return ret;
- }
-
protected LocalFilesystemURL URLforFullPath(String fullPath) {
Uri nativeUri = nativeUriForFullPath(fullPath);
if (nativeUri != null) {
@@ -128,56 +116,6 @@ public class LocalFilesystem extends Filesystem {
return this.URLforFullPath(this.fullPathForFilesystemPath(path));
}
- /**
- * Removes multiple repeated //s, and collapses processes ../s.
- */
- protected String normalizePath(String rawPath) {
- // If this is an absolute path, trim the leading "/" and replace it later
- boolean isAbsolutePath = rawPath.startsWith("/");
- if (isAbsolutePath) {
- rawPath = rawPath.replaceFirst("/+", "");
- }
- ArrayList<String> components = new ArrayList<String>(Arrays.asList(rawPath.split("/+")));
- for (int index = 0; index < components.size(); ++index) {
- if (components.get(index).equals("..")) {
- components.remove(index);
- if (index > 0) {
- components.remove(index-1);
- --index;
- }
- }
- }
- StringBuilder normalizedPath = new StringBuilder();
- for(String component: components) {
- normalizedPath.append("/");
- normalizedPath.append(component);
- }
- if (isAbsolutePath) {
- return normalizedPath.toString();
- } else {
- return normalizedPath.toString().substring(1);
- }
- }
-
-
- @Override
- public JSONObject makeEntryForFile(File file) {
- return makeEntryForNativeUri(Uri.fromFile(file));
- }
-
- @Override
- public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {
- File fp = new File(filesystemPathForURL(inputURL));
-
- if (!fp.exists()) {
- throw new FileNotFoundException();
- }
- if (!fp.canRead()) {
- throw new IOException();
- }
- return super.getEntryForLocalURL(inputURL);
- }
-
@Override
public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
@@ -203,7 +141,7 @@ public class LocalFilesystem extends Filesystem {
path += "/";
}
if (path.startsWith("/")) {
- requestedURL = URLforFilesystemPath(normalizePath(path));
+ requestedURL = URLforFullPath(normalizePath(path));
} else {
requestedURL = URLforFullPath(normalizePath(inputURL.path + "/" + path));
}
@@ -255,7 +193,13 @@ public class LocalFilesystem extends Filesystem {
return fp.delete();
}
- @Override
+ @Override
+ public boolean exists(LocalFilesystemURL inputURL) {
+ File fp = new File(filesystemPathForURL(inputURL));
+ return fp.exists();
+ }
+
+ @Override
public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException {
File directory = new File(filesystemPathForURL(inputURL));
return removeDirRecursively(directory);
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/356d3343/tests/tests.js
----------------------------------------------------------------------
diff --git a/tests/tests.js b/tests/tests.js
index adaa9ab..5735af1 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -3443,6 +3443,43 @@ exports.defineAutoTests = function () {
}, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider'));
});
});
+ describe('asset: URLs', function() {
+ it("file.spec.141 filePaths.applicationStorage", function() {
+ expect(cordova.file.applicationDirectory).toEqual('file:///android_asset/');
+ });
+ it("file.spec.142 assets should be enumerable", function(done) {
+ resolveLocalFileSystemURL('file:///android_asset/www/', function(entry) {
+ var reader = entry.createReader();
+ reader.readEntries(function (entries) {
+ expect(entries.length).not.toBe(0);
+ done();
+ }, failed.bind(null, done, 'reader.readEntries - Error during reading of entries from assets directory'));
+ }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));
+ });
+ it("file.spec.143 copyTo: asset -> temporary", function(done) {
+ var file2 = "entry.copy.file2b",
+ fullPath = joinURL(temp_root.fullPath, file2),
+ validateFile = function (entry) {
+ expect(entry.isFile).toBe(true);
+ expect(entry.isDirectory).toBe(false);
+ expect(entry.name).toCanonicallyMatch(file2);
+ expect(entry.fullPath).toCanonicallyMatch(fullPath);
+ expect(entry.filesystem.name).toEqual("temporary");
+ // cleanup
+ deleteEntry(entry.name, done);
+ },
+ transfer = function () {
+ resolveLocalFileSystemURL('file:///android_asset/www/index.html', function(entry) {
+ expect(entry.filesystem.name).toEqual('assets');
+ entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + entry.toURL() + ' to TEMPORAL root as: ' + file2));
+ }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));
+ };
+ // Delete any existing file to start things off
+ temp_root.getFile(file2, {}, function (entry) {
+ entry.remove(transfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));
+ }, transfer);
+ });
+ });
}
});
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[05/13] cordova-plugin-file git commit: android: Delete invalid
JavaDoc (lint errors)
Posted by ag...@apache.org.
android: Delete invalid JavaDoc (lint errors)
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/c35d9135
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/c35d9135
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/c35d9135
Branch: refs/heads/master
Commit: c35d9135b14c16410ba452a9a46fa6dfb8c832fb
Parents: 80f37d6
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Mar 9 13:17:39 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
src/android/FileUtils.java | 29 +----------------------------
1 file changed, 1 insertion(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/c35d9135/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index 676d297..cd6f9c1 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -65,7 +65,7 @@ public class FileUtils extends CordovaPlugin {
public static int QUOTA_EXCEEDED_ERR = 10;
public static int TYPE_MISMATCH_ERR = 11;
public static int PATH_EXISTS_ERR = 12;
-
+
public static int UNKNOWN_ERR = 1000;
private boolean configured = false;
@@ -638,7 +638,6 @@ public class FileUtils extends CordovaPlugin {
/**
* Read the list of files from this directory.
*
- * @param fileName the directory to read from
* @return a JSONArray containing JSONObjects that represent Entry objects.
* @throws FileNotFoundException if the directory is not found.
* @throws JSONException
@@ -661,8 +660,6 @@ public class FileUtils extends CordovaPlugin {
/**
* A setup method that handles the move/copy of files/directories
*
- * @param fileName to be copied/moved
- * @param newParent is the location where the file will be copied/moved to
* @param newName for the file directory to be called, if null use existing file name
* @param move if false do a copy, if true do a move
* @return a Entry object
@@ -699,7 +696,6 @@ public class FileUtils extends CordovaPlugin {
* some of the contents of the directory may be deleted.
* It is an error to attempt to delete the root directory of a filesystem.
*
- * @param filePath the directory to be removed
* @return a boolean representing success of failure
* @throws FileExistsException
* @throws NoModificationAllowedException
@@ -729,7 +725,6 @@ public class FileUtils extends CordovaPlugin {
* Deletes a file or directory. It is an error to attempt to delete a directory that is not empty.
* It is an error to attempt to delete the root directory of a filesystem.
*
- * @param filePath file or directory to be removed
* @return a boolean representing success of failure
* @throws NoModificationAllowedException
* @throws InvalidModificationException
@@ -787,11 +782,6 @@ public class FileUtils extends CordovaPlugin {
/**
* Look up the parent DirectoryEntry containing this Entry.
* If this Entry is the root of its filesystem, its parent is itself.
- *
- * @param filePath
- * @return
- * @throws JSONException
- * @throws IOException
*/
private JSONObject getParent(String baseURLstr) throws JSONException, IOException {
try {
@@ -810,11 +800,7 @@ public class FileUtils extends CordovaPlugin {
/**
* Returns a File that represents the current state of the file that this FileEntry represents.
*
- * @param filePath to entry
* @return returns a JSONObject represent a W3C File object
- * @throws FileNotFoundException
- * @throws JSONException
- * @throws MalformedURLException
*/
private JSONObject getFileMetadata(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {
try {
@@ -858,10 +844,7 @@ public class FileUtils extends CordovaPlugin {
/**
* Requests a filesystem in which to store application data.
*
- * @param type of file system requested
* @return a JSONObject representing the file system
- * @throws IOException
- * @throws JSONException
*/
private JSONArray requestAllFileSystems() throws IOException, JSONException {
JSONArray ret = new JSONArray();
@@ -939,14 +922,12 @@ public class FileUtils extends CordovaPlugin {
* Read the contents of a file.
* This is done in a background thread; the result is sent to the callback.
*
- * @param filename The name of the file.
* @param start Start position in the file.
* @param end End position to stop at (exclusive).
* @param callbackContext The context through which to send the result.
* @param encoding The encoding to return contents as. Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets)
* @param resultType The desired type of data to send to the callback.
* @return Contents of file.
- * @throws MalformedURLException
*/
public void readFileAs(final String srcURLstr, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) throws MalformedURLException {
try {
@@ -1012,12 +993,9 @@ public class FileUtils extends CordovaPlugin {
/**
* Write contents of file.
*
- * @param filename The name of the file.
* @param data The contents of the file.
* @param offset The position to begin writing the file.
* @param isBinary True if the file contents are base64-encoded binary data
- * @throws FileNotFoundException, IOException
- * @throws NoModificationAllowedException
*/
/**/
public long write(String srcURLstr, String data, int offset, boolean isBinary) throws FileNotFoundException, IOException, NoModificationAllowedException {
@@ -1037,11 +1015,6 @@ public class FileUtils extends CordovaPlugin {
/**
* Truncate the file to size
- *
- * @param filename
- * @param size
- * @throws FileNotFoundException, IOException
- * @throws NoModificationAllowedException
*/
private long truncateFile(String srcURLstr, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
try {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[02/13] cordova-plugin-file git commit: Tweak tests to fail if
deleteEntry fails (rather than time out)
Posted by ag...@apache.org.
Tweak tests to fail if deleteEntry fails (rather than time out)
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/9d789088
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/9d789088
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/9d789088
Branch: refs/heads/master
Commit: 9d789088bb557357b5651eeecf74eb90774b0525
Parents: 8f7b013
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Mar 10 10:27:54 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
tests/tests.js | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/9d789088/tests/tests.js
----------------------------------------------------------------------
diff --git a/tests/tests.js b/tests/tests.js
index c1471d7..1478aaf 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -131,6 +131,7 @@ exports.defineAutoTests = function () {
// deletes entry, if it exists
// entry.remove success callback is required: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#the-entry-interface
success = success || function() {};
+ error = error || failed.bind(null, success, 'deleteEntry failed.');
window.resolveLocalFileSystemURL(root.toURL() + '/' + name, function (entry) {
if (entry.isDirectory === true) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[06/13] cordova-plugin-file git commit: Tweak test case that failed
twice on error rather than just once
Posted by ag...@apache.org.
Tweak test case that failed twice on error rather than just once
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/1a79a051
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/1a79a051
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/1a79a051
Branch: refs/heads/master
Commit: 1a79a051ac09dc4c9619644404c687b2229c37e1
Parents: c35d913
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Mar 9 13:17:59 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
tests/tests.js | 1 -
1 file changed, 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/1a79a051/tests/tests.js
----------------------------------------------------------------------
diff --git a/tests/tests.js b/tests/tests.js
index 8710a54..c1471d7 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -2189,7 +2189,6 @@ exports.defineAutoTests = function () {
};
var reader = new FileReader();
reader.onloadend = verifier;
- reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + blob);
reader.readAsText(blob);
});
function writeDummyFile(writeBinary, callback, done) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[04/13] cordova-plugin-file git commit: android: Use
CordovaResourceApi rather than FileHelper
Posted by ag...@apache.org.
android: Use CordovaResourceApi rather than FileHelper
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/80f37d6c
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/80f37d6c
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/80f37d6c
Branch: refs/heads/master
Commit: 80f37d6c0389731ccf2bef7c23c064e854699faa
Parents: 2ed379c
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Mar 9 13:12:04 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
plugin.xml | 4 +-
src/android/FileHelper.java | 158 ----------------------------------
src/android/FileUtils.java | 6 +-
src/android/LocalFilesystem.java | 28 +++---
4 files changed, 16 insertions(+), 180 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/80f37d6c/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
index ac1bc17..10c0c65 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -28,6 +28,9 @@ xmlns:android="http://schemas.android.com/apk/res/android"
<keywords>cordova,file</keywords>
<repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git</repo>
<issue>https://issues.apache.org/jira/browse/CB/component/12320651</issue>
+ <engines>
+ <engine name="cordova-android" version=">=3.1.0" /><!-- Uses CordovaResourceApi -->
+ </engines>
<js-module src="www/DirectoryEntry.js" name="DirectoryEntry">
<clobbers target="window.DirectoryEntry" />
@@ -121,7 +124,6 @@ xmlns:android="http://schemas.android.com/apk/res/android"
<source-file src="src/android/NoModificationAllowedException.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/TypeMismatchException.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/FileUtils.java" target-dir="src/org/apache/cordova/file" />
- <source-file src="src/android/FileHelper.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/DirectoryManager.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/LocalFilesystemURL.java" target-dir="src/org/apache/cordova/file" />
<source-file src="src/android/Filesystem.java" target-dir="src/org/apache/cordova/file" />
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/80f37d6c/src/android/FileHelper.java
----------------------------------------------------------------------
diff --git a/src/android/FileHelper.java b/src/android/FileHelper.java
deleted file mode 100644
index 9e8b626..0000000
--- a/src/android/FileHelper.java
+++ /dev/null
@@ -1,158 +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.file;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.webkit.MimeTypeMap;
-
-import org.apache.cordova.CordovaInterface;
-import org.apache.cordova.LOG;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-
-public class FileHelper {
- private static final String LOG_TAG = "FileUtils";
- private static final String _DATA = "_data";
-
- /**
- * Returns the real path of the given URI string.
- * If the given URI string represents a content:// URI, the real path is retrieved from the media store.
- *
- * @param uriString the URI string of the audio/image/video
- * @param cordova the current application context
- * @return the full path to the file
- */
- @SuppressWarnings("deprecation")
- public static String getRealPath(String uriString, CordovaInterface cordova) {
- String realPath = null;
-
- if (uriString.startsWith("content://")) {
- String[] proj = { _DATA };
- Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
- int column_index = cursor.getColumnIndexOrThrow(_DATA);
- cursor.moveToFirst();
- realPath = cursor.getString(column_index);
- if (realPath == null) {
- LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString);
- }
- } else if (uriString.startsWith("file://")) {
- realPath = uriString.substring(7);
- if (realPath.startsWith("/android_asset/")) {
- LOG.e(LOG_TAG, "Cannot get real path for URI string %s because it is a file:///android_asset/ URI.", uriString);
- realPath = null;
- }
- } else {
- realPath = uriString;
- }
-
- return realPath;
- }
-
- /**
- * Returns the real path of the given URI.
- * If the given URI is a content:// URI, the real path is retrieved from the media store.
- *
- * @param uri the URI of the audio/image/video
- * @param cordova the current application context
- * @return the full path to the file
- */
- public static String getRealPath(Uri uri, CordovaInterface cordova) {
- return FileHelper.getRealPath(uri.toString(), cordova);
- }
-
- /**
- * Returns an input stream based on given URI string.
- *
- * @param uriString the URI string from which to obtain the input stream
- * @param cordova the current application context
- * @return an input stream into the data at the given URI or null if given an invalid URI string
- * @throws IOException
- */
- public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova) throws IOException {
- if (uriString.startsWith("content")) {
- Uri uri = Uri.parse(uriString);
- return cordova.getActivity().getContentResolver().openInputStream(uri);
- } else if (uriString.startsWith("file://")) {
- int question = uriString.indexOf("?");
- if (question > -1) {
- uriString = uriString.substring(0,question);
- }
- if (uriString.startsWith("file:///android_asset/")) {
- Uri uri = Uri.parse(uriString);
- String relativePath = uri.getPath().substring(15);
- return cordova.getActivity().getAssets().open(relativePath);
- } else {
- return new FileInputStream(getRealPath(uriString, cordova));
- }
- } else {
- return new FileInputStream(getRealPath(uriString, cordova));
- }
- }
-
- /**
- * 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.
- *
- * @param uriString the URI string to operate on
- * @return a path without the "file://" prefix
- */
- public static String stripFileProtocol(String uriString) {
- if (uriString.startsWith("file://")) {
- uriString = uriString.substring(7);
- }
- return uriString;
- }
-
- public static String getMimeTypeForExtension(String path) {
- String extension = path;
- int lastDot = extension.lastIndexOf('.');
- if (lastDot != -1) {
- extension = extension.substring(lastDot + 1);
- }
- // Convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
- extension = extension.toLowerCase(Locale.getDefault());
- if (extension.equals("3ga")) {
- return "audio/3gpp";
- }
- return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
- }
-
- /**
- * Returns the mime type of the data specified by the given URI string.
- *
- * @param uriString the URI string of the data
- * @return the mime type of the specified data
- */
- public static String getMimeType(String uriString, CordovaInterface cordova) {
- String mimeType = null;
-
- Uri uri = Uri.parse(uriString);
- if (uriString.startsWith("content://")) {
- mimeType = cordova.getActivity().getContentResolver().getType(uri);
- } else {
- mimeType = getMimeTypeForExtension(uri.getPath());
- }
-
- return mimeType;
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/80f37d6c/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index 08205d1..676d297 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -112,7 +112,7 @@ public class FileUtils extends CordovaPlugin {
if (fsRoot != null) {
File newRoot = new File(fsRoot);
if (newRoot.mkdirs() || newRoot.isDirectory()) {
- registerFilesystem(new LocalFilesystem(fsName, cordova, Uri.fromFile(newRoot)));
+ registerFilesystem(new LocalFilesystem(fsName, webView.getContext(), webView.getResourceApi(), Uri.fromFile(newRoot)));
installedFileSystems.add(fsName);
} else {
Log.d(LOG_TAG, "Unable to create root dir for filesystem \"" + fsName + "\", skipping");
@@ -192,8 +192,8 @@ public class FileUtils extends CordovaPlugin {
// Note: The temporary and persistent filesystems need to be the first two
// registered, so that they will match window.TEMPORARY and window.PERSISTENT,
// per spec.
- this.registerFilesystem(new LocalFilesystem("temporary", cordova, tempRoot));
- this.registerFilesystem(new LocalFilesystem("persistent", cordova, persistentRoot));
+ this.registerFilesystem(new LocalFilesystem("temporary", webView.getContext(), webView.getResourceApi(), tempRoot));
+ this.registerFilesystem(new LocalFilesystem("persistent", webView.getContext(), webView.getResourceApi(), persistentRoot));
this.registerFilesystem(new ContentFilesystem(cordova, webView));
registerExtraFileSystems(getExtraFileSystemsPreference(activity), getAvailableFileSystems(activity));
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/80f37d6c/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 28985fa..884771c 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -32,6 +32,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaResourceApi;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -44,14 +45,16 @@ import android.app.Activity;
public class LocalFilesystem extends Filesystem {
- private CordovaInterface cordova;
+ private final CordovaResourceApi resourceApi;
+ private final Context context;
- public LocalFilesystem(String name, CordovaInterface cordova, String rootPath) {
- this(name, cordova, Uri.fromFile(new File(rootPath)));
+ public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, String rootPath) {
+ this(name, context, resourceApi, Uri.fromFile(new File(rootPath)));
}
- public LocalFilesystem(String name, CordovaInterface cordova, Uri rootUri) {
+ public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, Uri rootUri) {
super(rootUri, name);
- this.cordova = cordova;
+ this.context = context;
+ this.resourceApi = resourceApi;
}
public String filesystemPathForFullPath(String fullPath) {
@@ -276,7 +279,7 @@ public class LocalFilesystem extends Filesystem {
try {
// Ensure that directories report a size of 0
metadata.put("size", file.isDirectory() ? 0 : file.length());
- metadata.put("type", FileHelper.getMimeType(file.getAbsolutePath(), cordova));
+ metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file)));
metadata.put("name", file.getName());
metadata.put("fullPath", inputURL.fullPath);
metadata.put("lastModifiedDate", file.lastModified());
@@ -520,7 +523,7 @@ public class LocalFilesystem extends Filesystem {
ReadFileCallback readFileCallback) throws IOException {
File file = new File(this.filesystemPathForURL(inputURL));
- String contentType = FileHelper.getMimeTypeForExtension(file.getAbsolutePath());
+ String contentType = resourceApi.getMimeType(Uri.fromFile(file));
if (end < 0) {
end = file.length();
@@ -588,19 +591,8 @@ public class LocalFilesystem extends Filesystem {
private void broadcastNewFile(LocalFilesystemURL inputURL) {
File file = new File(this.filesystemPathForURL(inputURL));
if (file.exists()) {
- //Get the activity
- Activity activity = this.cordova.getActivity();
-
- //Get the context
- Context context = activity.getApplicationContext();
-
- //Create the URI
Uri uri = Uri.fromFile(file);
-
- //Create the intent
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
-
- //Send broadcast of new file
context.sendBroadcast(intent);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[11/13] cordova-plugin-file git commit: CB-6428 android: Add support
for directory copies from assets -> filesystem
Posted by ag...@apache.org.
CB-6428 android: Add support for directory copies from assets -> filesystem
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/072acc73
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/072acc73
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/072acc73
Branch: refs/heads/master
Commit: 072acc733182c4736421e1a516706844e37747e0
Parents: 7051ad3
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Mar 10 22:43:14 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:08 2015 -0400
----------------------------------------------------------------------
src/android/AssetFilesystem.java | 2 +-
src/android/Filesystem.java | 7 +-
src/android/LocalFilesystem.java | 279 ++++++++++------------------------
tests/tests.js | 34 +++++
4 files changed, 119 insertions(+), 203 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/072acc73/src/android/AssetFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/AssetFilesystem.java b/src/android/AssetFilesystem.java
index 40968e0..c1c0d6f 100644
--- a/src/android/AssetFilesystem.java
+++ b/src/android/AssetFilesystem.java
@@ -211,7 +211,7 @@ public class AssetFilesystem extends Filesystem {
}
@Override
- boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException {
+ boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws NoModificationAllowedException {
throw new NoModificationAllowedException("Assets are read-only");
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/072acc73/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index 309c0b8..45047c8 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -198,7 +198,7 @@ public abstract class Filesystem {
return getEntryForLocalURL(LocalFilesystemURL.parse(parentUri));
}
- protected LocalFilesystemURL makeDestinationURL(String newName, LocalFilesystemURL srcURL, LocalFilesystemURL destURL) {
+ protected LocalFilesystemURL makeDestinationURL(String newName, LocalFilesystemURL srcURL, LocalFilesystemURL destURL, boolean isDirectory) {
// I know this looks weird but it is to work around a JSON bug.
if ("null".equals(newName) || "".equals(newName)) {
newName = srcURL.uri.getLastPathSegment();;
@@ -210,6 +210,9 @@ public abstract class Filesystem {
} else {
newDest = newDest + "/" + newName;
}
+ if (isDirectory) {
+ newDest += '/';
+ }
return LocalFilesystemURL.parse(newDest);
}
@@ -224,7 +227,7 @@ public abstract class Filesystem {
if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {
throw new NoModificationAllowedException("Cannot move file at source URL");
}
- final LocalFilesystemURL destination = makeDestinationURL(newName, srcURL, destURL);
+ final LocalFilesystemURL destination = makeDestinationURL(newName, srcURL, destURL, srcURL.isDirectory);
Uri srcNativeUri = srcFs.toNativeUri(srcURL);
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/072acc73/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 93ba2b0..cc0ff57 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -20,17 +20,12 @@ package org.apache.cordova.file;
import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Arrays;
-
import org.apache.cordova.CordovaResourceApi;
-import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -263,182 +258,72 @@ public class LocalFilesystem extends Filesystem {
return metadata;
}
- /**
- * Check to see if the user attempted to copy an entry into its parent without changing its name,
- * or attempted to copy a directory into a directory that it contains directly or indirectly.
- */
- private boolean isCopyOnItself(String src, String dest) {
-
- // This weird test is to determine if we are copying or moving a directory into itself.
- // Copy /sdcard/myDir to /sdcard/myDir-backup is okay but
- // Copy /sdcard/myDir to /sdcard/myDir/backup should throw an INVALID_MODIFICATION_ERR
- return dest.equals(src) || dest.startsWith(src + File.separator);
- }
-
- /**
- * Copy a file
- *
- * @param srcFile file to be copied
- * @param destFile destination to be copied to
- * @return a FileEntry object
- * @throws IOException
- * @throws InvalidModificationException
- * @throws JSONException
- */
- private JSONObject copyFile(File srcFile, File destFile) throws IOException, InvalidModificationException, JSONException {
- // Renaming a file to an existing directory should fail
- if (destFile.exists() && destFile.isDirectory()) {
- throw new InvalidModificationException("Can't rename a file to a directory");
+ private void copyFile(Filesystem srcFs, LocalFilesystemURL srcURL, File destFile, boolean move) throws IOException, InvalidModificationException, NoModificationAllowedException {
+ if (move) {
+ String realSrcPath = srcFs.filesystemPathForURL(srcURL);
+ if (realSrcPath != null) {
+ File srcFile = new File(realSrcPath);
+ if (srcFile.renameTo(destFile)) {
+ return;
+ }
+ // Trying to rename the file failed. Possibly because we moved across file system on the device.
+ }
}
- copyAction(srcFile, destFile);
-
- return makeEntryForFile(destFile);
- }
-
- /**
- * Moved this code into it's own method so moveTo could use it when the move is across file systems
- */
- private void copyAction(File srcFile, File destFile)
- throws FileNotFoundException, IOException {
- FileInputStream istream = new FileInputStream(srcFile);
- FileOutputStream ostream = new FileOutputStream(destFile);
- FileChannel input = istream.getChannel();
- FileChannel output = ostream.getChannel();
+ CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(srcFs.toNativeUri(srcURL));
+ resourceApi.copyResource(offr, new FileOutputStream(destFile));
- try {
- input.transferTo(0, input.size(), output);
- } finally {
- istream.close();
- ostream.close();
- input.close();
- output.close();
+ if (move) {
+ srcFs.removeFileAtLocalURL(srcURL);
}
}
- /**
- * Copy a directory
- *
- * @param srcDir directory to be copied
- * @param destinationDir destination to be copied to
- * @return a DirectoryEntry object
- * @throws JSONException
- * @throws IOException
- * @throws NoModificationAllowedException
- * @throws InvalidModificationException
- */
- private JSONObject copyDirectory(File srcDir, File destinationDir) throws JSONException, IOException, NoModificationAllowedException, InvalidModificationException {
- // Renaming a file to an existing directory should fail
- if (destinationDir.exists() && destinationDir.isFile()) {
- throw new InvalidModificationException("Can't rename a file to a directory");
- }
-
- // Check to make sure we are not copying the directory into itself
- if (isCopyOnItself(srcDir.getAbsolutePath(), destinationDir.getAbsolutePath())) {
- throw new InvalidModificationException("Can't copy itself into itself");
+ private void copyDirectory(Filesystem srcFs, LocalFilesystemURL srcURL, File dstDir, boolean move) throws IOException, NoModificationAllowedException, InvalidModificationException, FileExistsException {
+ if (move) {
+ String realSrcPath = srcFs.filesystemPathForURL(srcURL);
+ if (realSrcPath != null) {
+ File srcDir = new File(realSrcPath);
+ // If the destination directory already exists and is empty then delete it. This is according to spec.
+ if (dstDir.exists()) {
+ if (dstDir.list().length > 0) {
+ throw new InvalidModificationException("directory is not empty");
+ }
+ dstDir.delete();
+ }
+ // Try to rename the directory
+ if (srcDir.renameTo(dstDir)) {
+ return;
+ }
+ // Trying to rename the file failed. Possibly because we moved across file system on the device.
+ }
}
- // See if the destination directory exists. If not create it.
- if (!destinationDir.exists()) {
- if (!destinationDir.mkdir()) {
+ if (dstDir.exists()) {
+ if (dstDir.list().length > 0) {
+ throw new InvalidModificationException("directory is not empty");
+ }
+ } else {
+ if (!dstDir.mkdir()) {
// If we can't create the directory then fail
throw new NoModificationAllowedException("Couldn't create the destination directory");
}
}
-
- for (File file : srcDir.listFiles()) {
- File destination = new File(destinationDir.getAbsoluteFile() + File.separator + file.getName());
- if (file.isDirectory()) {
- copyDirectory(file, destination);
+ LocalFilesystemURL[] children = srcFs.listChildren(srcURL);
+ for (LocalFilesystemURL childLocalUrl : children) {
+ File target = new File(dstDir, new File(childLocalUrl.path).getName());
+ if (childLocalUrl.isDirectory) {
+ copyDirectory(srcFs, childLocalUrl, target, false);
} else {
- copyFile(file, destination);
+ copyFile(srcFs, childLocalUrl, target, false);
}
}
- return makeEntryForFile(destinationDir);
- }
-
- /**
- * Move a file
- *
- * @param srcFile file to be copied
- * @param destFile destination to be copied to
- * @return a FileEntry object
- * @throws IOException
- * @throws InvalidModificationException
- * @throws JSONException
- */
- private JSONObject moveFile(File srcFile, File destFile) throws IOException, JSONException, InvalidModificationException {
- // Renaming a file to an existing directory should fail
- if (destFile.exists() && destFile.isDirectory()) {
- throw new InvalidModificationException("Can't rename a file to a directory");
- }
-
- // Try to rename the file
- if (!srcFile.renameTo(destFile)) {
- // Trying to rename the file failed. Possibly because we moved across file system on the device.
- // Now we have to do things the hard way
- // 1) Copy all the old file
- // 2) delete the src file
- copyAction(srcFile, destFile);
- if (destFile.exists()) {
- srcFile.delete();
- } else {
- throw new IOException("moved failed");
- }
+ if (move) {
+ srcFs.recursiveRemoveFileAtLocalURL(srcURL);
}
-
- return makeEntryForFile(destFile);
}
- /**
- * Move a directory
- *
- * @param srcDir directory to be copied
- * @param destinationDir destination to be copied to
- * @return a DirectoryEntry object
- * @throws JSONException
- * @throws IOException
- * @throws InvalidModificationException
- * @throws NoModificationAllowedException
- * @throws FileExistsException
- */
- private JSONObject moveDirectory(File srcDir, File destinationDir) throws IOException, JSONException, InvalidModificationException, NoModificationAllowedException, FileExistsException {
- // Renaming a file to an existing directory should fail
- if (destinationDir.exists() && destinationDir.isFile()) {
- throw new InvalidModificationException("Can't rename a file to a directory");
- }
-
- // Check to make sure we are not copying the directory into itself
- if (isCopyOnItself(srcDir.getAbsolutePath(), destinationDir.getAbsolutePath())) {
- throw new InvalidModificationException("Can't move itself into itself");
- }
-
- // If the destination directory already exists and is empty then delete it. This is according to spec.
- if (destinationDir.exists()) {
- if (destinationDir.list().length > 0) {
- throw new InvalidModificationException("directory is not empty");
- }
- }
-
- // Try to rename the directory
- if (!srcDir.renameTo(destinationDir)) {
- // Trying to rename the directory failed. Possibly because we moved across file system on the device.
- // Now we have to do things the hard way
- // 1) Copy all the old files
- // 2) delete the src directory
- copyDirectory(srcDir, destinationDir);
- if (destinationDir.exists()) {
- removeDirRecursively(srcDir);
- } else {
- throw new IOException("moved failed");
- }
- }
-
- return makeEntryForFile(destinationDir);
- }
-
@Override
public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {
@@ -451,45 +336,39 @@ public class LocalFilesystem extends Filesystem {
throw new FileNotFoundException("The source does not exist");
}
- if (LocalFilesystem.class.isInstance(srcFs)) {
- /* Same FS, we can shortcut with NSFileManager operations */
-
- // Figure out where we should be copying to
- final LocalFilesystemURL destinationURL = makeDestinationURL(newName, srcURL, destURL);
-
- String srcFilesystemPath = srcFs.filesystemPathForURL(srcURL);
- File sourceFile = new File(srcFilesystemPath);
- String destFilesystemPath = this.filesystemPathForURL(destinationURL);
- File destinationFile = new File(destFilesystemPath);
-
- if (!sourceFile.exists()) {
- // The file/directory we are copying doesn't exist so we should fail.
- throw new FileNotFoundException("The source does not exist");
- }
-
- // Check to see if source and destination are the same file
- if (sourceFile.getAbsolutePath().equals(destinationFile.getAbsolutePath())) {
- throw new InvalidModificationException("Can't copy a file onto itself");
- }
-
- if (sourceFile.isDirectory()) {
- if (move) {
- return moveDirectory(sourceFile, destinationFile);
- } else {
- return copyDirectory(sourceFile, destinationFile);
- }
- } else {
- if (move) {
- return moveFile(sourceFile, destinationFile);
- } else {
- return copyFile(sourceFile, destinationFile);
- }
- }
-
- } else {
- // Need to copy the hard way
- return super.copyFileToURL(destURL, newName, srcFs, srcURL, move);
- }
+ // Figure out where we should be copying to
+ final LocalFilesystemURL destinationURL = makeDestinationURL(newName, srcURL, destURL, srcURL.isDirectory);
+
+ Uri dstNativeUri = toNativeUri(destinationURL);
+ Uri srcNativeUri = srcFs.toNativeUri(srcURL);
+ // Check to see if source and destination are the same file
+ if (dstNativeUri.equals(srcNativeUri)) {
+ throw new InvalidModificationException("Can't copy onto itself");
+ }
+
+ if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {
+ throw new InvalidModificationException("Source URL is read-only (cannot move)");
+ }
+
+ File destFile = new File(dstNativeUri.getPath());
+ if (destFile.exists()) {
+ if (!srcURL.isDirectory && destFile.isDirectory()) {
+ throw new InvalidModificationException("Can't copy/move a file to an existing directory");
+ } else if (srcURL.isDirectory && destFile.isFile()) {
+ throw new InvalidModificationException("Can't copy/move a directory to an existing file");
+ }
+ }
+
+ if (srcURL.isDirectory) {
+ // E.g. Copy /sdcard/myDir to /sdcard/myDir/backup
+ if (dstNativeUri.toString().startsWith(srcNativeUri.toString() + '/')) {
+ throw new InvalidModificationException("Can't copy directory into itself");
+ }
+ copyDirectory(srcFs, srcURL, destFile, move);
+ } else {
+ copyFile(srcFs, srcURL, destFile, move);
+ }
+ return makeEntryForURL(destinationURL);
}
@Override
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/072acc73/tests/tests.js
----------------------------------------------------------------------
diff --git a/tests/tests.js b/tests/tests.js
index 5735af1..239a0d3 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -3480,6 +3480,40 @@ exports.defineAutoTests = function () {
}, transfer);
});
});
+ it("file.spec.144 copyTo: asset directory", function (done) {
+ var srcUrl = 'file:///android_asset/www/plugins/org.apache.cordova.file';
+ var dstDir = "entry.copy.dstDir";
+ var dstPath = joinURL(root.fullPath, dstDir);
+ // create a new directory entry to kick off it
+ deleteEntry(dstDir, function () {
+ resolveLocalFileSystemURL(srcUrl, function(directory) {
+ directory.copyTo(root, dstDir, function (directory) {
+ expect(directory).toBeDefined();
+ expect(directory.isFile).toBe(false);
+ expect(directory.isDirectory).toBe(true);
+ expect(directory.fullPath).toCanonicallyMatch(dstPath);
+ expect(directory.name).toCanonicallyMatch(dstDir);
+ root.getDirectory(dstDir, {
+ create : false
+ }, function (dirEntry) {
+ expect(dirEntry).toBeDefined();
+ expect(dirEntry.isFile).toBe(false);
+ expect(dirEntry.isDirectory).toBe(true);
+ expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
+ expect(dirEntry.name).toCanonicallyMatch(dstDir);
+ dirEntry.getFile('www/File.js', {
+ create : false
+ }, function (fileEntry) {
+ expect(fileEntry).toBeDefined();
+ expect(fileEntry.isFile).toBe(true);
+ // cleanup
+ deleteEntry(dstDir, done);
+ }, failed.bind(null, done, 'dirEntry.getFile - Error getting subfile'));
+ }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory'));
+ }, failed.bind(null, done, 'directory.copyTo - Error copying directory'));
+ }, failed.bind(null, done, 'resolving src dir'));
+ }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
+ });
}
});
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[09/13] cordova-plugin-file git commit: android: Use
`CordovaResourceApi.mapUriToFile()` rather than own custom logic in
ContentFilesystem
Posted by ag...@apache.org.
android: Use `CordovaResourceApi.mapUriToFile()` rather than own custom logic in ContentFilesystem
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/81ea13cf
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/81ea13cf
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/81ea13cf
Branch: refs/heads/master
Commit: 81ea13cf783359ee9db26bfd89bebcba241858e0
Parents: 4d1c277
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Mar 9 14:19:52 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
src/android/ContentFilesystem.java | 21 ++-------------------
1 file changed, 2 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/81ea13cf/src/android/ContentFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java
index 79e1ecc..f577054 100644
--- a/src/android/ContentFilesystem.java
+++ b/src/android/ContentFilesystem.java
@@ -251,15 +251,6 @@ public class ContentFilesystem extends Filesystem {
return cursor;
}
- protected String filesystemPathForCursor(Cursor cursor) {
- final String[] LOCAL_FILE_PROJECTION = { MediaStore.Images.Media.DATA };
- int columnIndex = cursor.getColumnIndex(LOCAL_FILE_PROJECTION[0]);
- if (columnIndex != -1) {
- return cursor.getString(columnIndex);
- }
- return null;
- }
-
protected Integer resourceSizeForCursor(Cursor cursor) {
int columnIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
if (columnIndex != -1) {
@@ -285,16 +276,8 @@ public class ContentFilesystem extends Filesystem {
@Override
public String filesystemPathForURL(LocalFilesystemURL url) {
- Cursor cursor = openCursorForURL(url);
- try {
- if (cursor != null && cursor.moveToFirst()) {
- return filesystemPathForCursor(cursor);
- }
- } finally {
- if (cursor != null)
- cursor.close();
- }
- return null;
+ File f = resourceApi.mapUriToFile(url.URL);
+ return f == null ? null : f.getAbsolutePath();
}
@Override
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[10/13] cordova-plugin-file git commit: android: Add
`listChildren()`: Java-consumable version of `readEntriesAtLocalURL()`
Posted by ag...@apache.org.
android: Add `listChildren()`: Java-consumable version of `readEntriesAtLocalURL()`
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/7051ad35
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/7051ad35
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/7051ad35
Branch: refs/heads/master
Commit: 7051ad35890bf37d17f18ea56d71d796e160fc0c
Parents: 356d334
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Mar 10 22:42:06 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:08 2015 -0400
----------------------------------------------------------------------
src/android/AssetFilesystem.java | 14 +++++---------
src/android/ContentFilesystem.java | 7 +++----
src/android/Filesystem.java | 13 ++++++++++++-
src/android/LocalFilesystem.java | 21 ++++++++++-----------
4 files changed, 30 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/7051ad35/src/android/AssetFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/AssetFilesystem.java b/src/android/AssetFilesystem.java
index 7a54e43..40968e0 100644
--- a/src/android/AssetFilesystem.java
+++ b/src/android/AssetFilesystem.java
@@ -97,27 +97,23 @@ public class AssetFilesystem extends Filesystem {
@Override
- public JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
- String[] files;
+ public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {
String pathNoSlashes = inputURL.path.substring(1);
if (pathNoSlashes.endsWith("/")) {
pathNoSlashes = pathNoSlashes.substring(0, pathNoSlashes.length() - 1);
}
+ String[] files;
try {
files = assetManager.list(pathNoSlashes);
} catch (IOException e) {
throw new FileNotFoundException();
}
- JSONArray entries = new JSONArray();
- if (files != null) {
- for (String file : files) {
- Uri newNativeUri = nativeUriForFullPath(new File(inputURL.path, file).getPath());
- entries.put(makeEntryForNativeUri(newNativeUri));
- }
+ LocalFilesystemURL[] entries = new LocalFilesystemURL[files.length];
+ for (int i = 0; i < files.length; ++i) {
+ entries[i] = URLforFullPath(new File(inputURL.path, files[i]).getPath());
}
-
return entries;
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/7051ad35/src/android/ContentFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java
index 25c6489..eab0b03 100644
--- a/src/android/ContentFilesystem.java
+++ b/src/android/ContentFilesystem.java
@@ -112,11 +112,10 @@ public class ContentFilesystem extends Filesystem {
throw new NoModificationAllowedException("Cannot remove content url");
}
- @Override
- public JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL)
- throws FileNotFoundException {
+ @Override
+ public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {
throw new UnsupportedOperationException("readEntriesAtLocalURL() not supported for content:. Use resolveLocalFileSystemURL instead.");
- }
+ }
@Override
public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/7051ad35/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index 724976d..309c0b8 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -106,7 +106,18 @@ public abstract class Filesystem {
abstract boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException;
- abstract JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException;
+ abstract LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException;
+
+ public final JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
+ LocalFilesystemURL[] children = listChildren(inputURL);
+ JSONArray entries = new JSONArray();
+ if (children != null) {
+ for (LocalFilesystemURL url : children) {
+ entries.put(makeEntryForURL(url));
+ }
+ }
+ return entries;
+ }
abstract JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException;
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/7051ad35/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 83c1384..93ba2b0 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -219,8 +219,8 @@ public class LocalFilesystem extends Filesystem {
}
}
- @Override
- public JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
+ @Override
+ public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {
File fp = new File(filesystemPathForURL(inputURL));
if (!fp.exists()) {
@@ -228,15 +228,14 @@ public class LocalFilesystem extends Filesystem {
throw new FileNotFoundException();
}
- JSONArray entries = new JSONArray();
-
- if (fp.isDirectory()) {
- File[] files = fp.listFiles();
- for (int i = 0; i < files.length; i++) {
- if (files[i].canRead()) {
- entries.put(makeEntryForFile(files[i]));
- }
- }
+ File[] files = fp.listFiles();
+ if (files == null) {
+ // inputURL is a directory
+ return null;
+ }
+ LocalFilesystemURL[] entries = new LocalFilesystemURL[files.length];
+ for (int i = 0; i < files.length; i++) {
+ entries[i] = URLforFilesystemPath(files[i].getPath());
}
return entries;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[08/13] cordova-plugin-file git commit: android: Use Uri.parse rather
than manual parsing in resolveLocalFileSystemURI
Posted by ag...@apache.org.
android: Use Uri.parse rather than manual parsing in resolveLocalFileSystemURI
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/4d1c2770
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/4d1c2770
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/4d1c2770
Branch: refs/heads/master
Commit: 4d1c27708df6aaff82ff1ebafda330d13cbbfc8b
Parents: 1a79a05
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Mar 9 13:48:58 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:07 2015 -0400
----------------------------------------------------------------------
src/android/FileUtils.java | 34 ++++++++--------------------------
1 file changed, 8 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/4d1c2770/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index cd6f9c1..0063b43 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -584,44 +584,26 @@ public class FileUtils extends CordovaPlugin {
/**
* Allows the user to look up the Entry for a file or directory referred to by a local URI.
*
- * @param url of the file/directory to look up
+ * @param uriString of the file/directory to look up
* @return a JSONObject representing a Entry from the filesystem
* @throws MalformedURLException if the url is not valid
* @throws FileNotFoundException if the file does not exist
* @throws IOException if the user can't read the file
* @throws JSONException
*/
- private JSONObject resolveLocalFileSystemURI(String url) throws IOException, JSONException {
+ private JSONObject resolveLocalFileSystemURI(String uriString) throws IOException, JSONException {
LocalFilesystemURL inputURL;
- if (url == null) {
+ if (uriString == null) {
throw new MalformedURLException("Unrecognized filesystem URL");
}
-
- /* Backwards-compatibility: Check for file:// urls */
- if (url.startsWith("file:/")) {
- if (!url.startsWith("file://")) {
- url = "file:///" + url.substring(6);
- }
- String decoded = URLDecoder.decode(url, "UTF-8");
- /* This looks like a file url. Get the path, and see if any handlers recognize it. */
- String path;
- int questionMark = decoded.indexOf("?");
- int pathEnd;
- if (questionMark < 0) {
- pathEnd = decoded.length();
- } else {
- pathEnd = questionMark;
- }
+ Uri uri = Uri.parse(uriString);
- int thirdSlash = decoded.indexOf("/", 7);
- if (thirdSlash < 0 || thirdSlash > pathEnd) {
- path = "";
- } else {
- path = decoded.substring(thirdSlash, pathEnd);
- }
+ /* Backwards-compatibility: Check for file:// urls */
+ if ("file".equals(uri.getScheme())) {
+ String path = uri.getPath();
inputURL = this.filesystemURLforLocalPath(path);
} else {
- inputURL = new LocalFilesystemURL(url);
+ inputURL = new LocalFilesystemURL(uri);
}
try {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org
[13/13] cordova-plugin-file git commit: android: Don't use
LimitedInputStream when reading entire file (optimization)
Posted by ag...@apache.org.
android: Don't use LimitedInputStream when reading entire file (optimization)
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/80cf1de4
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/80cf1de4
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/80cf1de4
Branch: refs/heads/master
Commit: 80cf1de400b43ab64facc821f5354beb34f412f3
Parents: 072acc7
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Mar 10 22:50:58 2015 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Mar 11 11:35:08 2015 -0400
----------------------------------------------------------------------
src/android/Filesystem.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/80cf1de4/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index 45047c8..46786f3 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -263,7 +263,10 @@ public abstract class Filesystem {
if (start > 0) {
ofrr.inputStream.skip(start);
}
- LimitedInputStream inputStream = new LimitedInputStream(ofrr.inputStream, numBytesToRead);
+ InputStream inputStream = ofrr.inputStream;
+ if (end < ofrr.length) {
+ inputStream = new LimitedInputStream(inputStream, numBytesToRead);
+ }
readFileCallback.handleData(inputStream, ofrr.mimeType);
} finally {
ofrr.inputStream.close();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org