X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/85e9a40dbeb521029a592a3d85e9fa583cce0c19..5dc43aab3cc1243f9989dd6a0c7dd3350c3f709b:/src/com/owncloud/android/operations/RenameFileOperation.java diff --git a/src/com/owncloud/android/operations/RenameFileOperation.java b/src/com/owncloud/android/operations/RenameFileOperation.java index fd97c581..1c636fba 100644 --- a/src/com/owncloud/android/operations/RenameFileOperation.java +++ b/src/com/owncloud/android/operations/RenameFileOperation.java @@ -1,10 +1,9 @@ /* ownCloud Android client application - * Copyright (C) 2012 Bartek Przybylski + * Copyright (C) 2012-2013 ownCloud Inc. * * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -24,12 +23,13 @@ import java.io.IOException; import org.apache.jackrabbit.webdav.client.methods.DavMethodBase; //import org.apache.jackrabbit.webdav.client.methods.MoveMethod; -import android.util.Log; +import android.accounts.Account; +import com.owncloud.android.Log_OC; import com.owncloud.android.datamodel.DataStorageManager; import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.files.services.FileDownloader; import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.utils.FileStorageUtils; import eu.alefzero.webdav.WebdavClient; import eu.alefzero.webdav.WebdavUtils; @@ -41,14 +41,16 @@ import eu.alefzero.webdav.WebdavUtils; */ public class RenameFileOperation extends RemoteOperation { - private static final String TAG = RemoveFileOperation.class.getSimpleName(); + private static final String TAG = RenameFileOperation.class.getSimpleName(); private static final int RENAME_READ_TIMEOUT = 10000; private static final int RENAME_CONNECTION_TIMEOUT = 5000; private OCFile mFile; + private Account mAccount; private String mNewName; + private String mNewRemotePath; private DataStorageManager mStorageManager; @@ -56,12 +58,15 @@ public class RenameFileOperation extends RemoteOperation { * Constructor * * @param file OCFile instance describing the remote file or folder to rename + * @param account OwnCloud account containing the remote file * @param newName New name to set as the name of file. * @param storageManager Reference to the local database corresponding to the account where the file is contained. */ - public RenameFileOperation(OCFile file, String newName, DataStorageManager storageManager) { + public RenameFileOperation(OCFile file, Account account, String newName, DataStorageManager storageManager) { mFile = file; + mAccount = account; mNewName = newName; + mNewRemotePath = null; mStorageManager = storageManager; } @@ -80,7 +85,7 @@ public class RenameFileOperation extends RemoteOperation { RemoteOperationResult result = null; LocalMoveMethod move = null; - String newRemotePath = null; + mNewRemotePath = null; try { if (mNewName.equals(mFile.getFileName())) { return new RemoteOperationResult(ResultCode.OK); @@ -88,7 +93,10 @@ public class RenameFileOperation extends RemoteOperation { String parent = (new File(mFile.getRemotePath())).getParent(); parent = (parent.endsWith(OCFile.PATH_SEPARATOR)) ? parent : parent + OCFile.PATH_SEPARATOR; - newRemotePath = parent + mNewName; + mNewRemotePath = parent + mNewName; + if (mFile.isDirectory()) { + mNewRemotePath += OCFile.PATH_SEPARATOR; + } // check if the new name is valid in the local file system if (!isValidNewName()) { @@ -96,34 +104,22 @@ public class RenameFileOperation extends RemoteOperation { } // check if a file with the new name already exists - if (client.existsFile(newRemotePath) || // remote check could fail by network failure, or by indeterminate behavior of HEAD for folders ... - mStorageManager.getFileByPath(newRemotePath) != null) { // ... so local check is convenient + if (client.existsFile(mNewRemotePath) || // remote check could fail by network failure. by indeterminate behavior of HEAD for folders ... + mStorageManager.getFileByPath(mNewRemotePath) != null) { // ... so local check is convenient return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); } move = new LocalMoveMethod( client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath()), - client.getBaseUri() + WebdavUtils.encodePath(newRemotePath)); + client.getBaseUri() + WebdavUtils.encodePath(mNewRemotePath)); int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT); if (move.succeeded()) { - // create new OCFile instance for the renamed file - /*OCFile newFile = new OCFile(mStorageManager.getFileById(mFile.getParentId()).getRemotePath() + mNewName; // TODO - NOT CREATE NEW OCFILE; ADD setFileName METHOD - OCFile oldFile = mFile; - mFile = newFile; */ - mFile.setFileName(mNewName); - - // try to rename the local copy of the file - if (mFile.isDown()) { - File f = new File(mFile.getStoragePath()); - String newStoragePath = f.getParent() + mNewName; - if (f.renameTo(new File(newStoragePath))) { - mFile.setStoragePath(newStoragePath); - } - // else - NOTHING: the link to the local file is kept although the local name can't be updated - // TODO - study conditions when this could be a problem + if (mFile.isDirectory()) { + saveLocalDirectory(); + + } else { + saveLocalFile(); + } - - //mStorageManager.removeFile(oldFile, false); - mStorageManager.saveFile(mFile); /* *} else if (mFile.isDirectory() && (status == 207 || status >= 500)) { @@ -141,11 +137,11 @@ public class RenameFileOperation extends RemoteOperation { move.getResponseBodyAsString(); // exhaust response, although not interesting result = new RemoteOperationResult(move.succeeded(), status); - Log.i(TAG, "Rename " + mFile.getRemotePath() + " to " + newRemotePath + ": " + result.getLogMessage()); + Log_OC.i(TAG, "Rename " + mFile.getRemotePath() + " to " + mNewRemotePath + ": " + result.getLogMessage()); } catch (Exception e) { result = new RemoteOperationResult(e); - Log.e(TAG, "Rename " + mFile.getRemotePath() + " to " + ((newRemotePath==null) ? mNewName : newRemotePath) + ": " + result.getLogMessage(), e); + Log_OC.e(TAG, "Rename " + mFile.getRemotePath() + " to " + ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + result.getLogMessage(), e); } finally { if (move != null) @@ -155,6 +151,35 @@ public class RenameFileOperation extends RemoteOperation { } + private void saveLocalDirectory() { + mStorageManager.moveDirectory(mFile, mNewRemotePath); + String localPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile); + File localDir = new File(localPath); + if (localDir.exists()) { + localDir.renameTo(new File(FileStorageUtils.getSavePath(mAccount.name) + mNewRemotePath)); + // TODO - if renameTo fails, children files that are already down will result unlinked + } + } + + private void saveLocalFile() { + mFile.setFileName(mNewName); + + // try to rename the local copy of the file + if (mFile.isDown()) { + File f = new File(mFile.getStoragePath()); + String parentStoragePath = f.getParent(); + if (!parentStoragePath.endsWith(File.separator)) + parentStoragePath += File.separator; + if (f.renameTo(new File(parentStoragePath + mNewName))) { + mFile.setStoragePath(parentStoragePath + mNewName); + } + // else - NOTHING: the link to the local file is kept although the local name can't be updated + // TODO - study conditions when this could be a problem + } + + mStorageManager.saveFile(mFile); + } + /** * Checks if the new name to set is valid in the file system * @@ -166,21 +191,27 @@ public class RenameFileOperation extends RemoteOperation { * * TODO move this method, and maybe FileDownload.get***Path(), to a class with utilities specific for the interactions with the file system * - * @return 'True' if a temporal file named with the name to set could be created in the file system where - * local files are stored. + * @return 'True' if a temporal file named with the name to set could be created in the file system where + * local files are stored. + * @throws IOException When the temporal folder can not be created. */ - private boolean isValidNewName() { + private boolean isValidNewName() throws IOException { // check tricky names if (mNewName == null || mNewName.length() <= 0 || mNewName.contains(File.separator) || mNewName.contains("%")) { return false; } // create a test file - String tmpFolder = FileDownloader.getTemporalPath(""); - File testFile = new File(tmpFolder + mNewName); + String tmpFolderName = FileStorageUtils.getTemporalPath(""); + File testFile = new File(tmpFolderName + mNewName); + File tmpFolder = testFile.getParentFile(); + tmpFolder.mkdirs(); + if (!tmpFolder.isDirectory()) { + throw new IOException("Unexpected error: temporal directory could not be created"); + } try { testFile.createNewFile(); // return value is ignored; it could be 'false' because the file already existed, that doesn't invalidate the name } catch (IOException e) { - Log.i(TAG, "Test for validity of name " + mNewName + " in the file system failed"); + Log_OC.i(TAG, "Test for validity of name " + mNewName + " in the file system failed"); return false; } boolean result = (testFile.exists() && testFile.isFile()); @@ -192,8 +223,7 @@ public class RenameFileOperation extends RemoteOperation { } - - // move operation - TODO: find out why org.apache.jackrabbit.webdav.client.methods.MoveMethod is not used instead ¿? + // move operation private class LocalMoveMethod extends DavMethodBase { public LocalMoveMethod(String uri, String dest) {