// ISSUE 5: if the user is not running the app (this is a service!), this can be very intrusive; a notification should be preferred
Intent i = new Intent(mContext, ConflictsResolveActivity.class);
i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
- i.putExtra("remotepath", file.getRemotePath());
- i.putExtra("localpath", mPath);
- i.putExtra("account", mOCAccount);
+ i.putExtra(ConflictsResolveActivity.EXTRA_FILE, file);
+ i.putExtra(ConflictsResolveActivity.EXTRA_ACCOUNT, mOCAccount);
mContext.startActivity(i);
}
// TODO save other errors in some point where the user can inspect them later;
import com.owncloud.android.operations.UploadFileOperation;
import com.owncloud.android.ui.activity.FileDetailActivity;
import com.owncloud.android.ui.fragment.FileDetailFragment;
+import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.OwnCloudVersion;
import eu.alefzero.webdav.OnDatatransferProgressListener;
*/
private void saveUploadedFile() {
OCFile file = mCurrentUpload.getFile();
+ long syncDate = System.currentTimeMillis();
+ file.setLastSyncDateForData(syncDate);
/// new PROPFIND to keep data consistent with server in theory, should return the same we already have
PropFindMethod propfind = null;
RemoteOperationResult result = null;
- long syncDate = System.currentTimeMillis();
try {
propfind = new PropFindMethod(mUploadClient.getBaseUri() + WebdavUtils.encodePath(mCurrentUpload.getRemotePath()));
int status = mUploadClient.executeMethod(propfind);
MultiStatus resp = propfind.getResponseBodyAsMultiStatus();
WebdavEntry we = new WebdavEntry(resp.getResponses()[0],
mUploadClient.getBaseUri().getPath());
- OCFile newFile = fillOCFile(we);
- newFile.setStoragePath(file.getStoragePath());
- newFile.setKeepInSync(file.keepInSync());
- newFile.setLastSyncDateForProperties(syncDate);
- file = newFile;
+ updateOCFile(file, we);
+ file.setLastSyncDateForProperties(syncDate);
} else {
mUploadClient.exhaustResponse(propfind.getResponseBodyAsStream());
propfind.releaseConnection();
}
- file.setLastSyncDateForData(syncDate); // this is right, no matter if the PROPFIND was successful or not
- if (!result.isSuccess() && !mCurrentUpload.getRemotePath().equals(file.getRemotePath())) {
- // true when the file was automatically renamed to avoid an overwrite ; yes, this is a bit obscure...
- OCFile newFile = new OCFile(mCurrentUpload.getRemotePath());
- newFile.setCreationTimestamp(file.getCreationTimestamp());
- newFile.setFileLength(file.getFileLength());
- newFile.setMimetype(file.getMimetype());
- newFile.setModificationTimestamp(file.getModificationTimestamp());
- newFile.setLastSyncDateForProperties(file.getLastSyncDateForProperties());
- newFile.setStoragePath(file.getStoragePath());
- newFile.setKeepInSync(file.keepInSync());
- // newFile.setEtag(file.getEtag())
- file = newFile;
+ if (mCurrentUpload.wasRenamed()) {
+ OCFile oldFile = mCurrentUpload.getOldFile();
+ if (!oldFile.fileExists()) {
+ // just a name coincidence
+ file.setStoragePath(oldFile.getStoragePath());
+
+ } else {
+ // conflict resolved with 'Keep both' by the user
+ File localFile = new File(oldFile.getStoragePath());
+ File newLocalFile = new File(FileStorageUtils.getDefaultSavePathFor(mCurrentUpload.getAccount().name, file));
+ boolean renameSuccessed = localFile.renameTo(newLocalFile);
+ if (renameSuccessed) {
+ file.setStoragePath(newLocalFile.getAbsolutePath());
+
+ } else {
+ // poor solution
+ Log.d(TAG, "DAMN IT: local rename failed after uploading a file with a new name already existing both in the remote account and the local database (should be due to a conflict solved with 'keep both'");
+ file.setStoragePath(null);
+ // not so fine:
+ // - local file will be kept there as 'trash' until is download (and overwritten) again from the server;
+ // - user will see as 'not down' a file that was just upload
+ // BUT:
+ // - no loss of data happened
+ // - when the user downloads again the renamed and original file from the server, local file names and contents will be correctly synchronized with names and contents in server
+ }
+ oldFile.setStoragePath(null);
+ mStorageManager.saveFile(oldFile);
+ }
}
mStorageManager.saveFile(file);
}
- private OCFile fillOCFile(WebdavEntry we) {
- OCFile file = new OCFile(we.decodedPath());
+ private void updateOCFile(OCFile file, WebdavEntry we) {
file.setCreationTimestamp(we.createTimestamp());
file.setFileLength(we.contentLength());
file.setMimetype(we.contentType());
file.setModificationTimestamp(we.modifiedTimesamp());
// file.setEtag(mCurrentDownload.getEtag()); // TODO Etag, where available
- return file;
}
private Account mAccount;
private OCFile mFile;
+ private OCFile mOldFile;
private String mRemotePath = null;
private boolean mIsInstant = false;
private boolean mRemoteFolderToBeCreated = false;
private boolean mForceOverwrite = false;
+ private boolean mWasRenamed = false;
PutMethod mPutMethod = null;
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
+
public UploadFileOperation( Account account,
OCFile file,
return mFile;
}
+ public OCFile getOldFile() {
+ return mOldFile;
+ }
+
public String getStoragePath() {
return mFile.getStoragePath();
}
public String getRemotePath() {
- //return mFile.getRemotePath(); // DON'T MAKE THIS ; the remotePath used can be different to mFile.getRemotePath() if mForceOverwrite is 'false'; see run(...)
- return mRemotePath;
+ return mFile.getRemotePath();
}
public String getMimeType() {
return mForceOverwrite;
}
+ public boolean wasRenamed() {
+ return mWasRenamed;
+ }
public Set<OnDatatransferProgressListener> getDataTransferListeners() {
return mDataTransferListeners;
try {
/// rename the file to upload, if necessary
if (!mForceOverwrite) {
- mRemotePath = getAvailableRemotePath(client, mRemotePath);
+ String remotePath = getAvailableRemotePath(client, mRemotePath);
+ mWasRenamed = !remotePath.equals(mRemotePath);
+ if (mWasRenamed) {
+ createNewOCFile(remotePath);
+ }
}
/// perform the upload
}
+ private void createNewOCFile(String newRemotePath) {
+ // a new OCFile instance must be created for a new remote path
+ OCFile newFile = new OCFile(newRemotePath);
+ newFile.setCreationTimestamp(mFile.getCreationTimestamp());
+ newFile.setFileLength(mFile.getFileLength());
+ newFile.setMimetype(mFile.getMimetype());
+ newFile.setModificationTimestamp(mFile.getModificationTimestamp());
+ // newFile.setEtag(mFile.getEtag())
+ newFile.setKeepInSync(mFile.keepInSync());
+ newFile.setLastSyncDateForProperties(mFile.getLastSyncDateForProperties());
+ newFile.setLastSyncDateForData(mFile.getLastSyncDateForData());
+ newFile.setStoragePath(mFile.getStoragePath());
+ newFile.setParentId(mFile.getParentId());
+ mOldFile = mFile;
+ mFile = newFile;
+ }
+
+
public boolean isSuccess(int status) {
return ((status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT));
}
package com.owncloud.android.ui.activity;
import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
import com.owncloud.android.ui.dialog.ConflictsResolveDialog.Decision;
*/
public class ConflictsResolveActivity extends SherlockFragmentActivity implements OnConflictDecisionMadeListener {
+ public static final String EXTRA_FILE = "FILE";
+ public static final String EXTRA_ACCOUNT = "ACCOUNT";
+
private String TAG = ConflictsResolveActivity.class.getSimpleName();
- private String mRemotePath;
+ //private String mRemotePath;
- private String mLocalPath;
+ //private String mLocalPath;
+ private OCFile mFile;
private Account mOCAccount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mRemotePath = getIntent().getStringExtra("remotepath");
- mLocalPath = getIntent().getStringExtra("localpath");
- mOCAccount = getIntent().getParcelableExtra("account");
- ConflictsResolveDialog d = ConflictsResolveDialog.newInstance(mRemotePath, this);
+
+ //mRemotePath = getIntent().getStringExtra("remotepath");
+ //mLocalPath = getIntent().getStringExtra("localpath");
+ mFile = getIntent().getParcelableExtra(EXTRA_FILE);
+ mOCAccount = getIntent().getParcelableExtra(EXTRA_ACCOUNT);
+ ConflictsResolveDialog d = ConflictsResolveDialog.newInstance(mFile.getRemotePath(), this);
d.showDialog(this);
}
return;
}
i.putExtra(FileUploader.KEY_ACCOUNT, mOCAccount);
- i.putExtra(FileUploader.KEY_REMOTE_FILE, mRemotePath);
- i.putExtra(FileUploader.KEY_LOCAL_FILE, mLocalPath);
+ //i.putExtra(FileUploader.KEY_REMOTE_FILE, mRemotePath);
+ //i.putExtra(FileUploader.KEY_LOCAL_FILE, mLocalPath);
+ i.putExtra(FileUploader.KEY_FILE, mFile);
i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
startService(i);
if (!result.isSuccess()) {\r
if (result.getCode() == ResultCode.SYNC_CONFLICT) {\r
Intent i = new Intent(getActivity(), ConflictsResolveActivity.class);\r
- //i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);\r
- i.putExtra("remotepath", mFile.getRemotePath());\r
- i.putExtra("localpath", mFile.getStoragePath());\r
- i.putExtra("account", mAccount);\r
+ i.putExtra(ConflictsResolveActivity.EXTRA_FILE, mFile);\r
+ i.putExtra(ConflictsResolveActivity.EXTRA_ACCOUNT, mAccount);\r
startActivity(i);\r
\r
} else {\r