X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/30c934fe37872b2f1e57678299df24b05b0b873d..00482b6dcb1e98da39df54374f7098b51d66bee5:/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 709eda2b..a4cfa021 100644 --- a/src/com/owncloud/android/operations/RenameFileOperation.java +++ b/src/com/owncloud/android/operations/RenameFileOperation.java @@ -1,10 +1,13 @@ -/* ownCloud Android client application - * Copyright (C) 2012 Bartek Przybylski +/** + * ownCloud Android client application + * + * @author David A. Velasco + * @author masensio + * 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 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 @@ -21,48 +24,42 @@ package com.owncloud.android.operations; import java.io.File; 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 com.owncloud.android.datamodel.DataStorageManager; +import com.owncloud.android.MainApp; import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.files.services.FileDownloader; -import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +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.common.utils.Log_OC; +import com.owncloud.android.lib.resources.files.RenameRemoteFileOperation; +import com.owncloud.android.operations.common.SyncOperation; +import com.owncloud.android.utils.FileStorageUtils; -import eu.alefzero.webdav.WebdavClient; -import eu.alefzero.webdav.WebdavUtils; /** * Remote operation performing the rename of a remote file (or folder?) in the ownCloud server. - * - * @author David A. Velasco */ -public class RenameFileOperation extends RemoteOperation { +public class RenameFileOperation extends SyncOperation { - private static final String TAG = RemoveFileOperation.class.getSimpleName(); - - private static final int RENAME_READ_TIMEOUT = 10000; - private static final int RENAME_CONNECTION_TIMEOUT = 5000; + private static final String TAG = RenameFileOperation.class.getSimpleName(); - private OCFile mFile; + private String mRemotePath; private String mNewName; - private DataStorageManager mStorageManager; + private String mNewRemotePath; + /** * Constructor * - * @param file OCFile instance describing the remote file or folder to rename + * @param remotePath RemotePath of the OCFile instance describing the remote file or + * folder to rename * @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) { - mFile = file; + public RenameFileOperation(String remotePath, String newName) { + mRemotePath = remotePath; mNewName = newName; - mStorageManager = storageManager; + mNewRemotePath = null; } public OCFile getFile() { @@ -76,148 +73,123 @@ public class RenameFileOperation extends RemoteOperation { * @param client Client object to communicate with the remote ownCloud server. */ @Override - protected RemoteOperationResult run(WebdavClient client) { + protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; - LocalMoveMethod move = null; - //MoveMethod move = null; // TODO find out why not use this - String newRemotePath = null; - try { - if (mNewName.equals(mFile.getFileName())) { - return new RemoteOperationResult(ResultCode.OK); - } + mFile = getStorageManager().getFileByPath(mRemotePath); - newRemotePath = (new File(mFile.getRemotePath())).getParent() + mNewName; - - // check if the new name is valid in the local file system + // check if the new name is valid in the local file system + try { if (!isValidNewName()) { return new RemoteOperationResult(ResultCode.INVALID_LOCAL_FILE_NAME); } - - // check if a remote file with the new name already exists - if (client.existsFile(newRemotePath)) { - return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); + String parent = (new File(mFile.getRemotePath())).getParent(); + parent = (parent.endsWith(OCFile.PATH_SEPARATOR)) ? parent : parent + + OCFile.PATH_SEPARATOR; + mNewRemotePath = parent + mNewName; + if (mFile.isFolder()) { + mNewRemotePath += OCFile.PATH_SEPARATOR; } - /*move = new MoveMethod( client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath()), - client.getBaseUri() + WebdavUtils.encodePath(newRemotePath), - false);*/ - move = new LocalMoveMethod( client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath()), - client.getBaseUri() + WebdavUtils.encodePath(newRemotePath)); - int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT); - if (move.succeeded()) { - // create new OCFile instance for the renamed file - OCFile newFile = obtainUpdatedFile(); - OCFile oldFile = mFile; - mFile = newFile; - - // try to rename the local copy of the file - if (oldFile.isDown()) { - File f = new File(oldFile.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 - } - - mStorageManager.removeFile(oldFile, false); - mStorageManager.saveFile(mFile); - + // check local overwrite + if (getStorageManager().getFileByPath(mNewRemotePath) != null) { + return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); } - move.getResponseBodyAsString(); // exhaust response, although not interesting - result = new RemoteOperationResult(move.succeeded(), status); - Log.i(TAG, "Rename " + mFile.getRemotePath() + " to " + newRemotePath + ": " + result.getLogMessage()); - - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log.e(TAG, "Rename " + mFile.getRemotePath() + " to " + ((newRemotePath==null) ? mNewName : newRemotePath) + ": " + result.getLogMessage(), e); + RenameRemoteFileOperation operation = new RenameRemoteFileOperation(mFile.getFileName(), + mFile.getRemotePath(), + mNewName, mFile.isFolder()); + result = operation.execute(client); + + if (result.isSuccess()) { + if (mFile.isFolder()) { + getStorageManager().moveLocalFile(mFile, mNewRemotePath, parent); + //saveLocalDirectory(); + + } else { + saveLocalFile(); + } + } - } finally { - if (move != null) - move.releaseConnection(); + } catch (IOException e) { + Log_OC.e(TAG, "Rename " + mFile.getRemotePath() + " to " + ((mNewRemotePath==null) ? + mNewName : mNewRemotePath) + ": " + + ((result!= null) ? result.getLogMessage() : ""), e); } + return result; } - + private void saveLocalFile() { + mFile.setFileName(mNewName); + + // try to rename the local copy of the file + if (mFile.isDown()) { + String oldPath = mFile.getStoragePath(); + File f = new File(oldPath); + String parentStoragePath = f.getParent(); + if (!parentStoragePath.endsWith(File.separator)) + parentStoragePath += File.separator; + if (f.renameTo(new File(parentStoragePath + mNewName))) { + String newPath = parentStoragePath + mNewName; + mFile.setStoragePath(newPath); + + // notify MediaScanner about removed file + getStorageManager().deleteFileInMediaScan(oldPath); + // notify to scan about new file + getStorageManager().triggerMediaScan(newPath); + } + // 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 + } + + 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. + * 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. + * 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 + * 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("%")) { + if (mNewName == null || mNewName.length() <= 0 || mNewName.contains(File.separator)) { 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 + 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()); - // cleaning ; result is ignored, since there is not much we could do in case of failure, but repeat and repeat... + // cleaning ; result is ignored, since there is not much we could do in case of failure, + // but repeat and repeat... testFile.delete(); return result; } - - /** - * Creates a new OCFile for the new remote name of the renamed file. - * - * @return OCFile object with the same information than mFile, but the renamed remoteFile and the storagePath (empty) - */ - private OCFile obtainUpdatedFile() { - OCFile file = new OCFile(mStorageManager.getFileById(mFile.getParentId()).getRemotePath() + mNewName); - file.setCreationTimestamp(mFile.getCreationTimestamp()); - file.setFileId(mFile.getFileId()); - file.setFileLength(mFile.getFileLength()); - file.setKeepInSync(mFile.keepInSync()); - file.setLastSyncDate(mFile.getLastSyncDate()); - file.setMimetype(mFile.getMimetype()); - file.setModificationTimestamp(mFile.getModificationTimestamp()); - file.setParentId(mFile.getParentId()); - return file; - } - - - // move operation - TODO: find out why org.apache.jackrabbit.webdav.client.methods.MoveMethod is not used instead ¿? - private class LocalMoveMethod extends DavMethodBase { - - public LocalMoveMethod(String uri, String dest) { - super(uri); - addRequestHeader(new org.apache.commons.httpclient.Header("Destination", dest)); - } - - @Override - public String getName() { - return "MOVE"; - } - - @Override - protected boolean isSuccess(int status) { - return status == 201 || status == 204; - } - - } - - }