OCFile stores again decoded remote paths; WebdavUtils.encode(...) added; fixed space...
authorDavid A. Velasco <dvelasco@solidgear.es>
Tue, 17 Jul 2012 10:59:15 +0000 (12:59 +0200)
committerDavid A. Velasco <dvelasco@solidgear.es>
Tue, 17 Jul 2012 10:59:15 +0000 (12:59 +0200)
12 files changed:
AndroidManifest.xml
src/eu/alefzero/owncloud/Uploader.java
src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java
src/eu/alefzero/owncloud/datamodel/OCFile.java
src/eu/alefzero/owncloud/files/services/FileUploader.java
src/eu/alefzero/owncloud/files/services/InstantUploadService.java
src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java
src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java
src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java
src/eu/alefzero/webdav/WebdavClient.java
src/eu/alefzero/webdav/WebdavEntry.java
src/eu/alefzero/webdav/WebdavUtils.java

index 53c014c..a547234 100644 (file)
@@ -18,7 +18,7 @@
  -->\r
 <manifest package="eu.alefzero.owncloud"\r
     android:versionCode="1"\r
-    android:versionName="0.1.160B" xmlns:android="http://schemas.android.com/apk/res/android">\r
+    android:versionName="0.1.161B" xmlns:android="http://schemas.android.com/apk/res/android">\r
 \r
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />\r
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />\r
index fcb22a2..354b007 100644 (file)
@@ -166,7 +166,7 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
                         null, null, null);\r
                 mCursor.moveToFirst();\r
                 pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH))\r
-                        + mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");\r
+                        + mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");   // TODO don't make this ; use WebdavUtils.encode in the right moment\r
             }\r
             a a = new a(pathToUpload, dirName);\r
             builder.setPositiveButton(R.string.common_ok, a);\r
@@ -251,10 +251,9 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
         // click on button\r
         switch (v.getId()) {\r
         case R.id.uploader_choose_folder:\r
-            mUploadPath = "/";\r
+            mUploadPath = "";   // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix\r
             for (String p : mParents)\r
-                mUploadPath += p + "/";\r
-            mUploadPath = Uri.encode(mUploadPath, "/");\r
+                mUploadPath += p + OCFile.PATH_SEPARATOR;\r
             Log.d(TAG, "Uploading file to dir " + mUploadPath);\r
 \r
             uploadFiles();\r
@@ -393,11 +392,11 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
                 final String display_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),\r
                              data = c.getString(c.getColumnIndex(Media.DATA));\r
                 local[i] = data;\r
-                remote[i] = mUploadPath + Uri.encode(display_name);\r
+                remote[i] = mUploadPath + display_name;\r
             } else if (uri.getScheme().equals("file")) {\r
                 final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme() + "://", ""));\r
                 local[i] = file.getAbsolutePath();\r
-                remote[i] = mUploadPath + Uri.encode(file.getName());\r
+                remote[i] = mUploadPath + file.getName();\r
             }\r
 \r
         }\r
index e1b62ef..c732f59 100644 (file)
@@ -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());
                 }
index ce9c03b..5cd54f6 100644 (file)
@@ -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;
     }
 
     /**
@@ -126,15 +123,6 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
     }
 
     /**
-     * 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();
     }
 
index 71c4258..5760596 100644 (file)
@@ -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;
index 1cf22c2..b666e59 100644 (file)
@@ -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) {
index 9f0c0dc..61975dd 100644 (file)
@@ -39,6 +39,7 @@ import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
 import eu.alefzero.owncloud.datamodel.OCFile;\r
 import eu.alefzero.owncloud.files.services.FileDownloader;\r
 import eu.alefzero.webdav.WebdavEntry;\r
+import eu.alefzero.webdav.WebdavUtils;\r
 \r
 /**\r
  * SyncAdapter implementation for syncing sample SyncAdapter contacts to the\r
@@ -176,7 +177,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                                                                          .getModificationTimestamp()) {\r
                     Intent intent = new Intent(this.getContext(), FileDownloader.class);\r
                     intent.putExtra(FileDownloader.EXTRA_ACCOUNT, getAccount());\r
-                    intent.putExtra(FileDownloader.EXTRA_FILE_PATH, file.getURLDecodedRemotePath());\r
+                    intent.putExtra(FileDownloader.EXTRA_FILE_PATH, file.getRemotePath());\r
                     intent.putExtra(FileDownloader.EXTRA_REMOTE_PATH, file.getRemotePath());\r
                     intent.putExtra(FileDownloader.EXTRA_FILE_SIZE, file.getFileLength());\r
                     file.setKeepInSync(true);\r
@@ -219,7 +220,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
             for (int i=0; i < files.size() && !mCancellation; i++) {\r
                 OCFile newFile = files.get(i);\r
                 if (newFile.getMimetype().equals("DIR")) {\r
-                    fetchData(getUri().toString() + newFile.getRemotePath(), syncResult, newFile.getFileId());\r
+                    fetchData(getUri().toString() + WebdavUtils.encode(newFile.getRemotePath()), syncResult, newFile.getFileId());\r
                 }\r
             }\r
             if (mCancellation) Log.d(TAG, "Leaving " + uri + " because cancellation request");\r
@@ -254,7 +255,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
     }\r
 \r
     private OCFile fillOCFile(WebdavEntry we) {\r
-        OCFile file = new OCFile(we.path());\r
+        OCFile file = new OCFile(we.decodedPath());\r
         file.setCreationTimestamp(we.createTimestamp());\r
         file.setFileLength(we.contentLength());\r
         file.setMimetype(we.contentType());\r
index e54913a..45f7c77 100644 (file)
@@ -117,7 +117,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
         if(savedInstanceState != null) {\r
             mDirs = savedInstanceState.getStringArray(KEY_DIR_ARRAY);\r
             mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);\r
-            mDirectories.add("/");\r
+            mDirectories.add(OCFile.PATH_SEPARATOR);\r
             if (mDirs != null)\r
                 for (String s : mDirs)\r
                     mDirectories.insert(s, 0);\r
@@ -244,12 +244,11 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                         AccountUtils.getCurrentOwnCloudAccount(this));\r
                 String remotepath = new String();\r
                 for (int j = mDirectories.getCount() - 2; j >= 0; --j) {\r
-                    remotepath += "/" + mDirectories.getItem(j);\r
+                    remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);\r
                 }\r
-                if (!remotepath.endsWith("/"))\r
-                    remotepath += "/";\r
+                if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))\r
+                    remotepath += OCFile.PATH_SEPARATOR;\r
                 remotepath += new File(filepath).getName();\r
-                remotepath = Uri.encode(remotepath, "/");\r
     \r
                 i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);\r
                 i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);\r
@@ -369,7 +368,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                 for (String s : mDirs)\r
                     mDirectories.add(s);\r
             } else {\r
-                mDirectories.add("/");\r
+                mDirectories.add(OCFile.PATH_SEPARATOR);\r
             }\r
                \r
             // Actionbar setup\r
@@ -456,16 +455,16 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                             String path;\r
                             if (mCurrentDir == null) {\r
                                 // this is just a patch; we should ensure that mCurrentDir never is null\r
-                                if (!mStorageManager.fileExists("/")) {\r
-                                    OCFile file = new OCFile("/");\r
+                                if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {\r
+                                    OCFile file = new OCFile(OCFile.PATH_SEPARATOR);\r
                                     mStorageManager.saveFile(file);\r
                                 }\r
-                                mCurrentDir = mStorageManager.getFileByPath("/");\r
+                                mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);\r
                             }\r
                             path = FileDisplayActivity.this.mCurrentDir.getRemotePath();\r
                             \r
                             // Create directory\r
-                            path += Uri.encode(directoryName) + "/";\r
+                            path += directoryName + OCFile.PATH_SEPARATOR;\r
                             Thread thread = new Thread(new DirectoryCreator(path, a));\r
                             thread.start();\r
     \r
index c94719e..7eb0c1b 100644 (file)
@@ -95,6 +95,7 @@ import eu.alefzero.owncloud.files.services.FileDownloader;
 import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;\r
 import eu.alefzero.owncloud.utils.OwnCloudVersion;\r
 import eu.alefzero.webdav.WebdavClient;\r
+import eu.alefzero.webdav.WebdavUtils;\r
 \r
 /**\r
  * This Fragment is used to display the details about a file.\r
@@ -223,7 +224,7 @@ public class FileDetailFragment extends SherlockFragment implements
                 Intent i = new Intent(getActivity(), FileDownloader.class);\r
                 i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);\r
                 i.putExtra(FileDownloader.EXTRA_REMOTE_PATH, mFile.getRemotePath());\r
-                i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getURLDecodedRemotePath());\r
+                i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getRemotePath());\r
                 i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength());\r
                 v.setEnabled(false);\r
                 getActivity().startService(i);\r
@@ -602,7 +603,7 @@ public class FileDetailFragment extends SherlockFragment implements
                 if (!newFilename.equals(mFile.getFileName())) {\r
                     FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
                     if (fdsm.getFileById(mFile.getFileId()) != null) {\r
-                        OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath()+"/"+newFilename);\r
+                        OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath() + OCFile.PATH_SEPARATOR + newFilename);\r
                         newFile.setCreationTimestamp(mFile.getCreationTimestamp());\r
                         newFile.setFileId(mFile.getFileId());\r
                         newFile.setFileLength(mFile.getFileLength());\r
@@ -643,11 +644,11 @@ public class FileDetailFragment extends SherlockFragment implements
             String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);\r
             OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));\r
             String webdav_path = AccountUtils.getWebdavPath(ocv);\r
-            Log.d("ASD", ""+baseUrl + webdav_path + mOld.getRemotePath());\r
+            Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encode(mOld.getRemotePath()));\r
 \r
-            Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + mNew.getRemotePath());\r
-            LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + mOld.getRemotePath(),\r
-                                             Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + mNew.getRemotePath());\r
+            Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encode(mNew.getRemotePath()));\r
+            LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + WebdavUtils.encode(mOld.getRemotePath()),\r
+                                             Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encode(mNew.getRemotePath()));\r
             \r
             try {\r
                 int status = wc.executeMethod(move);\r
@@ -771,9 +772,9 @@ public class FileDetailFragment extends SherlockFragment implements
             String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);\r
             OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));\r
             String webdav_path = AccountUtils.getWebdavPath(ocv);\r
-            Log.d("ASD", ""+baseUrl + webdav_path + mFileToRemove.getRemotePath());\r
+            Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encode(mFileToRemove.getRemotePath()));\r
 \r
-            DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + mFileToRemove.getRemotePath());\r
+            DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + WebdavUtils.encode(mFileToRemove.getRemotePath()));\r
             HttpMethodParams params = delete.getParams();\r
             params.setSoTimeout(1000);\r
             delete.setParams(params);\r
index dd3b4ea..9eafddc 100644 (file)
@@ -113,9 +113,16 @@ public class WebdavClient extends HttpClient {
                 new EasySSLSocketFactory(), 443));\r
     }\r
 \r
+    /**\r
+     * Downloads a file in remoteFilepath to the local targetPath.\r
+     * \r
+     * @param remoteFilepath    Path to the file in the remote server, URL DECODED. \r
+     * @param targetPath        Local path to save the downloaded file.\r
+     * @return                  'True' when the file is successfully downloaded.\r
+     */\r
     public boolean downloadFile(String remoteFilepath, File targetPath) {\r
         boolean ret = false;\r
-        GetMethod get = new GetMethod(mUri.toString() + remoteFilepath);\r
+        GetMethod get = new GetMethod(mUri.toString() + WebdavUtils.encode(remoteFilepath));\r
         HttpMethodParams params = get.getParams();\r
         params.setSoTimeout(0); // that means "infinite timeout"; it's the default value, but let's make it explicit\r
         get.setParams(params);\r
@@ -152,11 +159,11 @@ public class WebdavClient extends HttpClient {
     \r
     /**\r
      * Deletes a remote file via webdav\r
-     * @param remoteFilePath\r
+     * @param remoteFilePath       Remote file path of the file to delete, in URL DECODED format.\r
      * @return\r
      */\r
     public boolean deleteFile(String remoteFilePath){\r
-        DavMethod delete = new DeleteMethod(mUri.toString() + remoteFilePath);\r
+        DavMethod delete = new DeleteMethod(mUri.toString() + WebdavUtils.encode(remoteFilePath));\r
         try {\r
             executeMethod(delete);\r
         }  catch (Throwable e) {\r
@@ -170,6 +177,15 @@ public class WebdavClient extends HttpClient {
         mDataTransferListener = listener;\r
     }\r
     \r
+    /**\r
+     * Creates or update a file in the remote server with the contents of a local file.\r
+     * \r
+     * \r
+     * @param localFile         Path to the local file to upload.\r
+     * @param remoteTarget      Remote path to the file to create or update, URL DECODED\r
+     * @param contentType       MIME type of the file.\r
+     * @return                  'True' then the upload was successfully completed\r
+     */\r
     public boolean putFile(String localFile, String remoteTarget,\r
             String contentType) {\r
         boolean result = true;\r
@@ -180,7 +196,7 @@ public class WebdavClient extends HttpClient {
             FileRequestEntity entity = new FileRequestEntity(f, contentType);\r
             entity.setOnDatatransferProgressListener(mDataTransferListener);\r
             Log.e("ASD", f.exists() + " " + entity.getContentLength());\r
-            PutMethod put = new PutMethod(mUri.toString() + remoteTarget);\r
+            PutMethod put = new PutMethod(mUri.toString() + WebdavUtils.encode(remoteTarget));\r
             HttpMethodParams params = put.getParams();\r
             params.setSoTimeout(0); // that means "infinite timeout"; it's the default value, but let's make it explicit\r
             put.setParams(params);\r
@@ -218,9 +234,15 @@ public class WebdavClient extends HttpClient {
         return returnCode;\r
     }\r
 \r
+    /**\r
+     * Creates a remote directory with the received path.\r
+     * \r
+     * @param path      Path of the directory to create, URL DECODED\r
+     * @return          'True' when the directory is successfully created\r
+     */\r
     public boolean createDirectory(String path) {\r
         try {\r
-            MkColMethod mkcol = new MkColMethod(mUri.toString() + path);\r
+            MkColMethod mkcol = new MkColMethod(mUri.toString() + WebdavUtils.encode(path));\r
             int status = executeMethod(mkcol);\r
             Log.d(TAG, "Status returned " + status);\r
             Log.d(TAG, "uri: " + mkcol.getURI().toString());\r
index f4fbda4..84c96fb 100644 (file)
@@ -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;
index dc407b0..8e7c07b 100644 (file)
@@ -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;
+    }
 }