You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ia...@apache.org on 2014/01/07 16:28:05 UTC
git commit: Android: Better support for content urls and
cross-filesystem copy/move ops
Updated Branches:
refs/heads/dev b7882772b -> 68b29ccb4
Android: Better support for content urls and cross-filesystem copy/move ops
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/68b29ccb
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/68b29ccb
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/68b29ccb
Branch: refs/heads/dev
Commit: 68b29ccb4b5b0a115f018a058651daf0111cd709
Parents: b788277
Author: Ian Clelland <ic...@chromium.org>
Authored: Tue Jan 7 10:12:57 2014 -0500
Committer: Ian Clelland <ic...@chromium.org>
Committed: Tue Jan 7 10:27:30 2014 -0500
----------------------------------------------------------------------
src/android/ContentFilesystem.java | 63 +++++++++++++++++++++++--
src/android/FileUtils.java | 25 ++--------
src/android/Filesystem.java | 2 +
src/android/LocalFilesystem.java | 81 ++++++++++++++++-----------------
src/android/ReadFileCallback.java | 4 +-
5 files changed, 107 insertions(+), 68 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/68b29ccb/src/android/ContentFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/ContentFilesystem.java b/src/android/ContentFilesystem.java
index e19f5bc..03a1939 100644
--- a/src/android/ContentFilesystem.java
+++ b/src/android/ContentFilesystem.java
@@ -1,8 +1,10 @@
package org.apache.cordova.file;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import org.apache.cordova.CordovaInterface;
import org.json.JSONArray;
@@ -51,39 +53,63 @@ public class ContentFilesystem implements Filesystem {
throw new IOException();
}
}
+
@Override
public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
String fileName, JSONObject options, boolean directory) throws IOException {
throw new IOException("Cannot create content url");
}
+
@Override
public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL)
throws NoModificationAllowedException {
- throw new NoModificationAllowedException("Cannot remove content url");
+
+ String filePath = filesystemPathForURL(inputURL);
+ File file = new File(filePath);
+ try {
+ this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ MediaStore.Images.Media.DATA + " = ?",
+ new String[] { filePath });
+ } 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.
+ }
+ return file.delete();
}
+
@Override
public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL)
throws NoModificationAllowedException {
throw new NoModificationAllowedException("Cannot remove content url");
}
+
@Override
public JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL)
throws FileNotFoundException {
// TODO Auto-generated method stub
return null;
}
+
@Override
public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
// TODO Auto-generated method stub
return null;
}
+
@Override
public JSONObject getParentForLocalURL(LocalFilesystemURL inputURL)
throws IOException {
- // TODO Auto-generated method stub
- // Can probably use same impl as LFS
- return null;
+ LocalFilesystemURL newURL = new LocalFilesystemURL(inputURL.URL);
+
+ if (!("".equals(inputURL.fullPath) || "/".equals(inputURL.fullPath))) {
+ int end = inputURL.fullPath.endsWith("/") ? 1 : 0;
+ int lastPathStartsAt = inputURL.fullPath.lastIndexOf('/', inputURL.fullPath.length()-end)+1;
+ newURL.fullPath = newURL.fullPath.substring(0,lastPathStartsAt);
+ }
+ return getEntryForLocalURL(newURL);
}
+
@Override
public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
Filesystem srcFs, LocalFilesystemURL srcURL, boolean move)
@@ -92,12 +118,32 @@ public class ContentFilesystem implements Filesystem {
// TODO Auto-generated method stub
return null;
}
+
@Override
public void readFileAtURL(LocalFilesystemURL inputURL, int start, int end,
ReadFileCallback readFileCallback) throws IOException {
- // TODO Auto-generated method stub
+ int numBytesToRead = end - start;
+ byte[] bytes = new byte[numBytesToRead];
+ String contentType;
+
+ File file = new File(this.filesystemPathForURL(inputURL));
+ contentType = FileHelper.getMimeTypeForExtension(file.getAbsolutePath());
+ InputStream inputStream = new FileInputStream(file);
+ int numBytesRead = 0;
+ try {
+ if (start > 0) {
+ inputStream.skip(start);
+ }
+ while (numBytesToRead > 0 && (numBytesRead = inputStream.read(bytes, numBytesRead, numBytesToRead)) >= 0) {
+ numBytesToRead -= numBytesRead;
+ }
+ } finally {
+ inputStream.close();
+ }
+ readFileCallback.handleData(bytes, contentType);
}
+
@Override
public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
int offset, boolean isBinary) throws NoModificationAllowedException {
@@ -135,4 +181,11 @@ public class ContentFilesystem implements Filesystem {
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
+ String path = filesystemPathForURL(inputURL);
+ File file = new File(path);
+ return file.exists();
+ }
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/68b29ccb/src/android/FileUtils.java
----------------------------------------------------------------------
diff --git a/src/android/FileUtils.java b/src/android/FileUtils.java
index 25ea6b4..20a2700 100644
--- a/src/android/FileUtils.java
+++ b/src/android/FileUtils.java
@@ -61,6 +61,8 @@ 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;
public static int TEMPORARY = 0;
public static int PERSISTENT = 1;
@@ -312,9 +314,8 @@ public class FileUtils extends CordovaPlugin {
final String fname=args.getString(0);
threadhelper( new FileOp( ){
public void run() throws NoModificationAllowedException, InvalidModificationException, MalformedURLException {
- boolean success= remove(fname);
+ boolean success = remove(fname);
if (success) {
- notifyDelete(fname);
callbackContext.success();
} else {
callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);
@@ -439,6 +440,8 @@ public class FileUtils extends CordovaPlugin {
callbackContext.error(FileUtils.ENCODING_ERR);
} else if(e instanceof TypeMismatchException ) {
callbackContext.error(FileUtils.TYPE_MISMATCH_ERR);
+ } else {
+ callbackContext.error(FileUtils.UNKNOWN_ERR);
}
}
}
@@ -446,24 +449,6 @@ public class FileUtils extends CordovaPlugin {
}
/**
- * Need to check to see if we need to clean up the content store
- *
- * @param filePath the path to check
- */
- private void notifyDelete(String filePath) {
- String newFilePath = FileHelper.getRealPath(filePath, cordova);
- try {
- this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- MediaStore.Images.Media.DATA + " = ?",
- new String[] { newFilePath });
- } 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.
- }
- }
-
- /**
* 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
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/68b29ccb/src/android/Filesystem.java
----------------------------------------------------------------------
diff --git a/src/android/Filesystem.java b/src/android/Filesystem.java
index 7dd99f2..ba2c7bd 100644
--- a/src/android/Filesystem.java
+++ b/src/android/Filesystem.java
@@ -42,4 +42,6 @@ public interface Filesystem {
LocalFilesystemURL URLforFilesystemPath(String path);
+ boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL);
+
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/68b29ccb/src/android/LocalFilesystem.java
----------------------------------------------------------------------
diff --git a/src/android/LocalFilesystem.java b/src/android/LocalFilesystem.java
index 6634661..6c16e45 100644
--- a/src/android/LocalFilesystem.java
+++ b/src/android/LocalFilesystem.java
@@ -83,8 +83,7 @@ public class LocalFilesystem implements Filesystem {
@Override
public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {
- File fp = null;
- fp = new File(this.fsRoot + inputURL.fullPath); //TODO: Proper fs.join
+ File fp = new File(this.fsRoot + inputURL.fullPath); //TODO: Proper fs.join
if (!fp.exists()) {
throw new FileNotFoundException();
@@ -282,7 +281,7 @@ public class LocalFilesystem implements Filesystem {
* @param destination represents the destination file
* @return a File object that represents the destination
*/
- private File createDestination(String newName, File fp, File destination) {
+ private File createDestination(String newName, String oldName, File destination) {
File destFile = null;
// I know this looks weird but it is to work around a JSON bug.
@@ -293,7 +292,7 @@ public class LocalFilesystem implements Filesystem {
if (newName != null) {
destFile = new File(destination.getAbsolutePath() + File.separator + newName);
} else {
- destFile = new File(destination.getAbsolutePath() + File.separator + fp.getName());
+ destFile = new File(destination.getAbsolutePath() + File.separator + oldName);
}
return destFile;
}
@@ -461,42 +460,33 @@ public class LocalFilesystem implements Filesystem {
return makeEntryForFile(destinationDir, fsType);
}
-
@Override
public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {
-
- String newFileName = this.filesystemPathForURL(srcURL);
+ // Check to see if the destination directory exists
String newParent = this.filesystemPathForURL(destURL);
-
-
File destinationDir = new File(newParent);
if (!destinationDir.exists()) {
// The destination does not exist so we should fail.
throw new FileNotFoundException("The source does not exist");
}
-
+
+ // Figure out where we should be copying to
+ String originalName = srcURL.URL.getLastPathSegment();
+ final File destination = createDestination(newName, originalName, destinationDir);
if (LocalFilesystem.class.isInstance(srcFs)) {
-
/* Same FS, we can shortcut with NSFileManager operations */
-
-
- File source = new File(newFileName);
+ String srcFilesystemPath = this.filesystemPathForURL(srcURL);
+ File source = new File(srcFilesystemPath);
if (!source.exists()) {
// The file/directory we are copying doesn't exist so we should fail.
throw new FileNotFoundException("The source does not exist");
}
- // Figure out where we should be copying to
- File destination = createDestination(newName, source, destinationDir);
-
- //Log.d(LOG_TAG, "Source: " + source.getAbsolutePath());
- //Log.d(LOG_TAG, "Destin: " + destination.getAbsolutePath());
-
// Check to see if source and destination are the same file
if (source.getAbsolutePath().equals(destination.getAbsolutePath())) {
throw new InvalidModificationException("Can't copy a file onto itself");
@@ -510,36 +500,37 @@ public class LocalFilesystem implements Filesystem {
}
} else {
if (move) {
- JSONObject newFileEntry = moveFile(source, destination, destURL.filesystemType);
-
-/* // If we've moved a file given its content URI, we need to clean up.
- // TODO: Move this to where it belongs, in cross-fs mv code below.
- if (srcURL.URL.getScheme().equals("content")) {
- notifyDelete(fileName);
- }
-*/
- return newFileEntry;
+ return moveFile(source, destination, destURL.filesystemType);
} else {
return copyFile(source, destination, destURL.filesystemType);
}
}
-
} else {
-/* // Need to copy the hard way
- srcFs.readFileAtURL(srcURL, 0, -1, new ReadFileCallback() {
- void run(data, mimetype, errorcode) {
- if (data != null) {
- //write data to file
- // send success message -- call original callback?
+ // Need to copy the hard way
+ // First, check to see that we can do it
+ if (!move || srcFs.canRemoveFileAtLocalURL(srcURL)) {
+ srcFs.readFileAtURL(srcURL, 0, -1, new ReadFileCallback() {
+ public void handleData(byte[] data, String contentType) throws IOException {
+ if (data != null) {
+ //write data to file
+ FileOutputStream os = new FileOutputStream(destination);
+ os.write(data);
+ os.close();
+ } else {
+ throw new IOException("Cannot read file at source URL");
+ }
}
- // error
- }
- });
- return null; // Async, will return later
-*/
+ });
+ if (move) {
+ // Delete original
+ srcFs.removeFileAtLocalURL(srcURL);
+ }
+ return makeEntryForFile(destination, destURL.filesystemType);
+ } else {
+ throw new NoModificationAllowedException("Cannot move file at source URL");
+ }
}
- return null;
}
@Override
@@ -632,5 +623,11 @@ public class LocalFilesystem implements Filesystem {
}
+ @Override
+ public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
+ String path = filesystemPathForURL(inputURL);
+ File file = new File(path);
+ return file.exists();
+ }
}
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/68b29ccb/src/android/ReadFileCallback.java
----------------------------------------------------------------------
diff --git a/src/android/ReadFileCallback.java b/src/android/ReadFileCallback.java
index 77bb7da..b8ba02d 100644
--- a/src/android/ReadFileCallback.java
+++ b/src/android/ReadFileCallback.java
@@ -1,5 +1,7 @@
package org.apache.cordova.file;
+import java.io.IOException;
+
public interface ReadFileCallback {
- public void handleData(byte[] data, String contentType);
+ public void handleData(byte[] data, String contentType) throws IOException;
}