فهرست منبع

OCFile stores again decoded remote paths; WebdavUtils.encode(...) added; fixed space conversion in paths in multiple uploads; CLEAN THE APPLICATION CACHE AFTER INSTALLING

David A. Velasco 12 سال پیش
والد
کامیت
c6b553f635

+ 1 - 1
AndroidManifest.xml

@@ -18,7 +18,7 @@
  -->
 <manifest package="eu.alefzero.owncloud"
     android:versionCode="1"
-    android:versionName="0.1.160B" xmlns:android="http://schemas.android.com/apk/res/android">
+    android:versionName="0.1.161B" xmlns:android="http://schemas.android.com/apk/res/android">
 
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />

+ 5 - 6
src/eu/alefzero/owncloud/Uploader.java

@@ -166,7 +166,7 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
                         null, null, null);
                 mCursor.moveToFirst();
                 pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH))
-                        + mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");
+                        + mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");   // TODO don't make this ; use WebdavUtils.encode in the right moment
             }
             a a = new a(pathToUpload, dirName);
             builder.setPositiveButton(R.string.common_ok, a);
@@ -251,10 +251,9 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
         // click on button
         switch (v.getId()) {
         case R.id.uploader_choose_folder:
-            mUploadPath = "/";
+            mUploadPath = "";   // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix
             for (String p : mParents)
-                mUploadPath += p + "/";
-            mUploadPath = Uri.encode(mUploadPath, "/");
+                mUploadPath += p + OCFile.PATH_SEPARATOR;
             Log.d(TAG, "Uploading file to dir " + mUploadPath);
 
             uploadFiles();
@@ -393,11 +392,11 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
                 final String display_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
                              data = c.getString(c.getColumnIndex(Media.DATA));
                 local[i] = data;
-                remote[i] = mUploadPath + Uri.encode(display_name);
+                remote[i] = mUploadPath + display_name;
             } else if (uri.getScheme().equals("file")) {
                 final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme() + "://", ""));
                 local[i] = file.getAbsolutePath();
-                remote[i] = mUploadPath + Uri.encode(file.getName());
+                remote[i] = mUploadPath + file.getName();
             }
 
         }

+ 1 - 1
src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java

@@ -378,7 +378,7 @@ public class FileDataStorageManager implements DataStorageManager {
                 if (file.getStoragePath() == null) {
                     // try to find existing file and bind it with current account
                     File sdCard = Environment.getExternalStorageDirectory();
-                    File f = new File(sdCard.getAbsolutePath() + "/owncloud/" + mAccount.name + file.getURLDecodedRemotePath());
+                    File f = new File(sdCard.getAbsolutePath() + "/owncloud/" + mAccount.name + file.getRemotePath());
                     if (f.exists())
                         file.setStoragePath(f.getAbsolutePath());
                 }

+ 11 - 23
src/eu/alefzero/owncloud/datamodel/OCFile.java

@@ -40,6 +40,8 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         }
     };
 
+    public static final String PATH_SEPARATOR = "/";
+    
     private long mId;
     private long mParentId;
     private long mLength;
@@ -53,24 +55,19 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
     private boolean mKeepInSync;
 
     /**
-     * Create new {@link OCFile} with given path
+     * Create new {@link OCFile} with given path.
+     * 
+     * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
      * 
-     * @param path The remote path of the file
-     * @throws MalformedURLException 
+     * @param path The remote path of the file.
      */
     public OCFile(String path) {
         resetData();
         mNeedsUpdating = false;
-        /// dvelasco: the encoding / decoding problem should be completely translated to WebdavClient & WebdavEntry, but at this moment we are in a little hurry
-        if (path != null && path.length() > 0) {
-            try {
-                new URL("http://silly.test.com:8888" + path);
-            } catch (MalformedURLException e) {
-                throw new RuntimeException("Trying to create a OCFile with a non valid remote path: " + path , e);
-            }
-        } else throw new RuntimeException("Trying to create a OCFile with a non valid remote path: " + path);
-        // save encoded paths have a problem: normalization; this is a quick&dirty fix to avoid duplications
-        mRemotePath = Uri.encode(Uri.decode(path), "/");
+        if (path == null || path.length() <= 0 || !path.startsWith(PATH_SEPARATOR)) {
+            throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
+        }
+        mRemotePath = path;
     }
 
     /**
@@ -125,15 +122,6 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         return mRemotePath;
     }
 
-    /**
-     * Returns the remote path of the file on ownCloud
-     * 
-     * @return The remote path to the file
-     */
-    public String getURLDecodedRemotePath() {
-        return Uri.decode(mRemotePath);
-    }
-
     /**
      * Can be used to check, whether or not this file exists in the database
      * already
@@ -222,7 +210,7 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
      * @return The name of the file
      */
     public String getFileName() {
-        File f = new File(getURLDecodedRemotePath());
+        File f = new File(getRemotePath());
         return f.getName().length() == 0 ? "/" : f.getName();
     }
 

+ 0 - 3
src/eu/alefzero/owncloud/files/services/FileUploader.java

@@ -99,9 +99,6 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             mRemotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
         }
 
-        for (int i = 0; i < mRemotePaths.length; ++i)
-            mRemotePaths[i] = mRemotePaths[i].replace(' ', '+');
-
         if (mLocalPaths.length != mRemotePaths.length) {
             Log.e(TAG, "Remote paths and local paths are not equal!");
             return Service.START_NOT_STICKY;

+ 1 - 1
src/eu/alefzero/owncloud/files/services/InstantUploadService.java

@@ -148,7 +148,7 @@ public class InstantUploadService extends Service {
                 try {
                     status = wdc.executeMethod(mkcol);
                     Log.e(TAG, "mkcol returned " + status);
-                    wdc.putFile(filepath, INSTANT_UPLOAD_DIR + "/" + Uri.encode(filename), mimetype);
+                    wdc.putFile(filepath, INSTANT_UPLOAD_DIR + "/" + filename, mimetype);
                 } catch (HttpException e) {
                     e.printStackTrace();
                 } catch (IOException e) {

+ 4 - 3
src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java

@@ -39,6 +39,7 @@ import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
 import eu.alefzero.owncloud.datamodel.OCFile;
 import eu.alefzero.owncloud.files.services.FileDownloader;
 import eu.alefzero.webdav.WebdavEntry;
+import eu.alefzero.webdav.WebdavUtils;
 
 /**
  * SyncAdapter implementation for syncing sample SyncAdapter contacts to the
@@ -176,7 +177,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                                                                          .getModificationTimestamp()) {
                     Intent intent = new Intent(this.getContext(), FileDownloader.class);
                     intent.putExtra(FileDownloader.EXTRA_ACCOUNT, getAccount());
-                    intent.putExtra(FileDownloader.EXTRA_FILE_PATH, file.getURLDecodedRemotePath());
+                    intent.putExtra(FileDownloader.EXTRA_FILE_PATH, file.getRemotePath());
                     intent.putExtra(FileDownloader.EXTRA_REMOTE_PATH, file.getRemotePath());
                     intent.putExtra(FileDownloader.EXTRA_FILE_SIZE, file.getFileLength());
                     file.setKeepInSync(true);
@@ -219,7 +220,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
             for (int i=0; i < files.size() && !mCancellation; i++) {
                 OCFile newFile = files.get(i);
                 if (newFile.getMimetype().equals("DIR")) {
-                    fetchData(getUri().toString() + newFile.getRemotePath(), syncResult, newFile.getFileId());
+                    fetchData(getUri().toString() + WebdavUtils.encode(newFile.getRemotePath()), syncResult, newFile.getFileId());
                 }
             }
             if (mCancellation) Log.d(TAG, "Leaving " + uri + " because cancellation request");
@@ -254,7 +255,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
     }
 
     private OCFile fillOCFile(WebdavEntry we) {
-        OCFile file = new OCFile(we.path());
+        OCFile file = new OCFile(we.decodedPath());
         file.setCreationTimestamp(we.createTimestamp());
         file.setFileLength(we.contentLength());
         file.setMimetype(we.contentType());

+ 9 - 10
src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java

@@ -117,7 +117,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
         if(savedInstanceState != null) {
             mDirs = savedInstanceState.getStringArray(KEY_DIR_ARRAY);
             mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);
-            mDirectories.add("/");
+            mDirectories.add(OCFile.PATH_SEPARATOR);
             if (mDirs != null)
                 for (String s : mDirs)
                     mDirectories.insert(s, 0);
@@ -244,12 +244,11 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                         AccountUtils.getCurrentOwnCloudAccount(this));
                 String remotepath = new String();
                 for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
-                    remotepath += "/" + mDirectories.getItem(j);
+                    remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
                 }
-                if (!remotepath.endsWith("/"))
-                    remotepath += "/";
+                if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
+                    remotepath += OCFile.PATH_SEPARATOR;
                 remotepath += new File(filepath).getName();
-                remotepath = Uri.encode(remotepath, "/");
     
                 i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
                 i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
@@ -369,7 +368,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                 for (String s : mDirs)
                     mDirectories.add(s);
             } else {
-                mDirectories.add("/");
+                mDirectories.add(OCFile.PATH_SEPARATOR);
             }
                
             // Actionbar setup
@@ -456,16 +455,16 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                             String path;
                             if (mCurrentDir == null) {
                                 // this is just a patch; we should ensure that mCurrentDir never is null
-                                if (!mStorageManager.fileExists("/")) {
-                                    OCFile file = new OCFile("/");
+                                if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {
+                                    OCFile file = new OCFile(OCFile.PATH_SEPARATOR);
                                     mStorageManager.saveFile(file);
                                 }
-                                mCurrentDir = mStorageManager.getFileByPath("/");
+                                mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
                             }
                             path = FileDisplayActivity.this.mCurrentDir.getRemotePath();
                             
                             // Create directory
-                            path += Uri.encode(directoryName) + "/";
+                            path += directoryName + OCFile.PATH_SEPARATOR;
                             Thread thread = new Thread(new DirectoryCreator(path, a));
                             thread.start();
     

+ 9 - 8
src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java

@@ -95,6 +95,7 @@ import eu.alefzero.owncloud.files.services.FileDownloader;
 import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;
 import eu.alefzero.owncloud.utils.OwnCloudVersion;
 import eu.alefzero.webdav.WebdavClient;
+import eu.alefzero.webdav.WebdavUtils;
 
 /**
  * This Fragment is used to display the details about a file.
@@ -223,7 +224,7 @@ public class FileDetailFragment extends SherlockFragment implements
                 Intent i = new Intent(getActivity(), FileDownloader.class);
                 i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
                 i.putExtra(FileDownloader.EXTRA_REMOTE_PATH, mFile.getRemotePath());
-                i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getURLDecodedRemotePath());
+                i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getRemotePath());
                 i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength());
                 v.setEnabled(false);
                 getActivity().startService(i);
@@ -602,7 +603,7 @@ public class FileDetailFragment extends SherlockFragment implements
                 if (!newFilename.equals(mFile.getFileName())) {
                     FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());
                     if (fdsm.getFileById(mFile.getFileId()) != null) {
-                        OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath()+"/"+newFilename);
+                        OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath() + OCFile.PATH_SEPARATOR + newFilename);
                         newFile.setCreationTimestamp(mFile.getCreationTimestamp());
                         newFile.setFileId(mFile.getFileId());
                         newFile.setFileLength(mFile.getFileLength());
@@ -643,11 +644,11 @@ public class FileDetailFragment extends SherlockFragment implements
             String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);
             OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
             String webdav_path = AccountUtils.getWebdavPath(ocv);
-            Log.d("ASD", ""+baseUrl + webdav_path + mOld.getRemotePath());
+            Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encode(mOld.getRemotePath()));
 
-            Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + mNew.getRemotePath());
-            LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + mOld.getRemotePath(),
-                                             Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + mNew.getRemotePath());
+            Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encode(mNew.getRemotePath()));
+            LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + WebdavUtils.encode(mOld.getRemotePath()),
+                                             Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encode(mNew.getRemotePath()));
             
             try {
                 int status = wc.executeMethod(move);
@@ -771,9 +772,9 @@ public class FileDetailFragment extends SherlockFragment implements
             String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);
             OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
             String webdav_path = AccountUtils.getWebdavPath(ocv);
-            Log.d("ASD", ""+baseUrl + webdav_path + mFileToRemove.getRemotePath());
+            Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encode(mFileToRemove.getRemotePath()));
 
-            DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + mFileToRemove.getRemotePath());
+            DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + WebdavUtils.encode(mFileToRemove.getRemotePath()));
             HttpMethodParams params = delete.getParams();
             params.setSoTimeout(1000);
             delete.setParams(params);

+ 27 - 5
src/eu/alefzero/webdav/WebdavClient.java

@@ -113,9 +113,16 @@ public class WebdavClient extends HttpClient {
                 new EasySSLSocketFactory(), 443));
     }
 
+    /**
+     * Downloads a file in remoteFilepath to the local targetPath.
+     * 
+     * @param remoteFilepath    Path to the file in the remote server, URL DECODED. 
+     * @param targetPath        Local path to save the downloaded file.
+     * @return                  'True' when the file is successfully downloaded.
+     */
     public boolean downloadFile(String remoteFilepath, File targetPath) {
         boolean ret = false;
-        GetMethod get = new GetMethod(mUri.toString() + remoteFilepath);
+        GetMethod get = new GetMethod(mUri.toString() + WebdavUtils.encode(remoteFilepath));
         HttpMethodParams params = get.getParams();
         params.setSoTimeout(0); // that means "infinite timeout"; it's the default value, but let's make it explicit
         get.setParams(params);
@@ -152,11 +159,11 @@ public class WebdavClient extends HttpClient {
     
     /**
      * Deletes a remote file via webdav
-     * @param remoteFilePath
+     * @param remoteFilePath       Remote file path of the file to delete, in URL DECODED format.
      * @return
      */
     public boolean deleteFile(String remoteFilePath){
-        DavMethod delete = new DeleteMethod(mUri.toString() + remoteFilePath);
+        DavMethod delete = new DeleteMethod(mUri.toString() + WebdavUtils.encode(remoteFilePath));
         try {
             executeMethod(delete);
         }  catch (Throwable e) {
@@ -170,6 +177,15 @@ public class WebdavClient extends HttpClient {
         mDataTransferListener = listener;
     }
     
+    /**
+     * Creates or update a file in the remote server with the contents of a local file.
+     * 
+     * 
+     * @param localFile         Path to the local file to upload.
+     * @param remoteTarget      Remote path to the file to create or update, URL DECODED
+     * @param contentType       MIME type of the file.
+     * @return                  'True' then the upload was successfully completed
+     */
     public boolean putFile(String localFile, String remoteTarget,
             String contentType) {
         boolean result = true;
@@ -180,7 +196,7 @@ public class WebdavClient extends HttpClient {
             FileRequestEntity entity = new FileRequestEntity(f, contentType);
             entity.setOnDatatransferProgressListener(mDataTransferListener);
             Log.e("ASD", f.exists() + " " + entity.getContentLength());
-            PutMethod put = new PutMethod(mUri.toString() + remoteTarget);
+            PutMethod put = new PutMethod(mUri.toString() + WebdavUtils.encode(remoteTarget));
             HttpMethodParams params = put.getParams();
             params.setSoTimeout(0); // that means "infinite timeout"; it's the default value, but let's make it explicit
             put.setParams(params);
@@ -218,9 +234,15 @@ public class WebdavClient extends HttpClient {
         return returnCode;
     }
 
+    /**
+     * Creates a remote directory with the received path.
+     * 
+     * @param path      Path of the directory to create, URL DECODED
+     * @return          'True' when the directory is successfully created
+     */
     public boolean createDirectory(String path) {
         try {
-            MkColMethod mkcol = new MkColMethod(mUri.toString() + path);
+            MkColMethod mkcol = new MkColMethod(mUri.toString() + WebdavUtils.encode(path));
             int status = executeMethod(mkcol);
             Log.d(TAG, "Status returned " + status);
             Log.d(TAG, "uri: " + mkcol.getURI().toString());

+ 5 - 0
src/eu/alefzero/webdav/WebdavEntry.java

@@ -24,6 +24,7 @@ import org.apache.jackrabbit.webdav.property.DavProperty;
 import org.apache.jackrabbit.webdav.property.DavPropertyName;
 import org.apache.jackrabbit.webdav.property.DavPropertySet;
 
+import android.net.Uri;
 import android.util.Log;
 
 public class WebdavEntry {
@@ -92,6 +93,10 @@ public class WebdavEntry {
     public String path() {
         return mPath;
     }
+    
+    public String decodedPath() {
+        return Uri.decode(mPath);
+    }
 
     public String name() {
         return mName;

+ 19 - 0
src/eu/alefzero/webdav/WebdavUtils.java

@@ -23,6 +23,10 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
 
+import eu.alefzero.owncloud.datamodel.OCFile;
+
+import android.net.Uri;
+
 public class WebdavUtils {
     public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat(
             "dd.MM.yyyy hh:mm");
@@ -55,4 +59,19 @@ public class WebdavUtils {
         }
         return null;
     }
+
+    /**
+     * Encodes a path according to URI RFC 2396. 
+     * 
+     * If the received path doesn't start with "/", the method adds it.
+     * 
+     * @param remoteFilePath    Path
+     * @return                  Encoded path according to RFC 2396, always starting with "/"
+     */
+    public static String encode(String remoteFilePath) {
+        String encodedPath = Uri.encode(remoteFilePath, "/");
+        if (!encodedPath.startsWith("/"))
+            encodedPath = "/" + encodedPath;
+        return encodedPath;
+    }
 }