X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/e050da100938046e3d914ccbec7d9b955a27c748..afaa2879d192be067cae523b51dad75d89a6c6cb:/src/com/owncloud/android/operations/MoveFileOperation.java diff --git a/src/com/owncloud/android/operations/MoveFileOperation.java b/src/com/owncloud/android/operations/MoveFileOperation.java index f1a3f9f1..be254e7e 100644 --- a/src/com/owncloud/android/operations/MoveFileOperation.java +++ b/src/com/owncloud/android/operations/MoveFileOperation.java @@ -1,5 +1,8 @@ -/* ownCloud Android client application - * Copyright (C) 2012-2014 ownCloud Inc. +/** + * ownCloud Android client application + * + * @author David A. Velasco + * Copyright (C) 2015 ownCloud Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, @@ -17,33 +20,27 @@ package com.owncloud.android.operations; -import java.io.File; -import java.io.IOException; - +import com.owncloud.android.MainApp; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.lib.resources.files.RenameRemoteFileOperation; +import com.owncloud.android.lib.resources.files.MoveRemoteFileOperation; import com.owncloud.android.operations.common.SyncOperation; -import com.owncloud.android.utils.FileStorageUtils; -import com.owncloud.android.utils.Log_OC; import android.accounts.Account; /** * Operation mmoving an {@link OCFile} to a different folder. - * - * @author David A. Velasco */ public class MoveFileOperation extends SyncOperation { - private static final String TAG = MoveFileOperation.class.getSimpleName(); + //private static final String TAG = MoveFileOperation.class.getSimpleName(); + + private String mSrcPath; + private String mTargetParentPath; - private String mPath; - private Account mAccount; - private String mNewParentPath; private OCFile mFile; @@ -51,22 +48,20 @@ public class MoveFileOperation extends SyncOperation { /** * Constructor * - * @param path Remote path of the {@link OCFile} to move. - * @param newParentPath Path to the folder where the file will be moved into. + * @param srcPath Remote path of the {@link OCFile} to move. + * @param targetParentPath Path to the folder where the file will be moved into. * @param account OwnCloud account containing both the file and the target folder */ - public MoveFileOperation(String path, String newParentPath, Account account) { - mPath = path; - mNewParentPath = newParentPath; - mAccount = account; + public MoveFileOperation(String srcPath, String targetParentPath, Account account) { + mSrcPath = srcPath; + mTargetParentPath = targetParentPath; + if (!mTargetParentPath.endsWith(OCFile.PATH_SEPARATOR)) { + mTargetParentPath += OCFile.PATH_SEPARATOR; + } + mFile = null; } - public OCFile getFile() { - return mFile; - } - - /** * Performs the operation. * @@ -76,120 +71,35 @@ public class MoveFileOperation extends SyncOperation { protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; - mFile = getStorageManager().getFileByPath(mPath); - - // check if the new name is valid in the local file system - try { - String parentPath = (new File(mFile.getRemotePath())).getParent(); - parentPath = (parentPath.endsWith(OCFile.PATH_SEPARATOR)) - ? parentPath - : parentPath + OCFile.PATH_SEPARATOR; - - String mNewPath = mNewParentPath + mFile.getFileName(); - if (mFile.isFolder() && !mNewPath.endsWith(OCFile.PATH_SEPARATOR)) { - mNewPath += OCFile.PATH_SEPARATOR; - } - - // check local overwrite - if (getStorageManager().getFileByPath(mPath) != null) { - return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); - } - - MoveRemoteFileOperation operation = new MoveRemoteFileOperation( - mFile.getRemotePath(), - mNewPath, - mFile.isFolder() - ); - result = operation.execute(client); - - if (result.isSuccess()) { - if (mFile.isFolder()) { - saveLocalDirectory(); - - } else { - saveLocalFile(); - } - } - - } catch (IOException e) { - Log_OC.e(TAG, "Move " + mFile.getRemotePath() + " to " + - (mNewParentPath==null) + ": " + - ((result!= null) ? result.getLogMessage() : ""), e); + /// 1. check move validity + if (mTargetParentPath.startsWith(mSrcPath)) { + return new RemoteOperationResult(ResultCode.INVALID_MOVE_INTO_DESCENDANT); } - - return result; - } - - - private void saveLocalDirectory() { - getStorageManager().moveFolder(mFile, mNewParentPath); - String localPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile); - File localDir = new File(localPath); - if (localDir.exists()) { - localDir.renameTo(new File(FileStorageUtils.getSavePath(mAccount.name) + mNewParentPath)); - // 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 + mFile = getStorageManager().getFileByPath(mSrcPath); + if (mFile == null) { + return new RemoteOperationResult(ResultCode.FILE_NOT_FOUND); } - getStorageManager().saveFile(mFile); - } - - /** - * Checks if the new name to set is valid in the file system - * - * The only way to be sure is trying to create a file with that name. It's made in the temporal directory - * for downloads, out of any account, and then removed. - * - * IMPORTANT: The test must be made in the same file system where files are download. The internal storage - * could be formatted with a different file system. - * - * 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. - * @throws IOException When the temporal folder can not be created. - */ - 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 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"); + /// 2. remote move + String targetPath = mTargetParentPath + mFile.getFileName(); + if (mFile.isFolder()) { + targetPath += OCFile.PATH_SEPARATOR; } - 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_OC.i(TAG, "Test for validity of name " + mNewName + " in the file system failed"); - return false; - } - boolean result = (testFile.exists() && testFile.isFile()); + MoveRemoteFileOperation operation = new MoveRemoteFileOperation( + mSrcPath, + targetPath, + false + ); + result = operation.execute(client); - // cleaning ; result is ignored, since there is not much we could do in case of failure, but repeat and repeat... - testFile.delete(); + /// 3. local move + if (result.isSuccess()) { + getStorageManager().moveLocalFile(mFile, targetPath, mTargetParentPath); + } + // TODO handle ResultCode.PARTIAL_MOVE_DONE in client Activity, for the moment return result; } + }