Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import com.owncloud.android.MainApp;
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
import com.owncloud.android.lib.common.network.WebdavEntry;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.files.ReadFileRemoteOperation;
import com.owncloud.android.lib.resources.files.model.FileLockType;
Expand Down Expand Up @@ -497,9 +496,13 @@ public List<OCFile> getFolderImages(OCFile folder, boolean onlyOnDevice) {
}

public boolean saveFile(OCFile ocFile) {
Log_OC.d(TAG, "saving file: " + ocFile.getRemotePath());

boolean overridden = false;
final ContentValues cv = createContentValuesForFile(ocFile);
if (ocFile.isFolder()) {
// only refresh folder operation must update eTag otherwise content of the folder may stay as outdated
cv.remove(ProviderTableMeta.FILE_ETAG);
cv.remove(ProviderTableMeta.FILE_STORAGE_PATH);
}

Expand Down Expand Up @@ -547,46 +550,65 @@ public boolean saveFile(OCFile ocFile) {
}

/**
* traverses a files parent tree to be able to store a file with its parents. Throws a
* RemoteOperationFailedException in case the parent can't be retrieved.
* Ensures that an {@link OCFile} and all of its parent folders are stored locally.
* <p>
* If the file has no parent ID and is not the root folder, this method recursively:
* <ul>
* <li>Resolves the parent path</li>
* <li>Loads the parent from local storage or fetches it from the server</li>
* <li>Saves all missing parent folders</li>
* <li>Assigns the resolved parent ID to the file</li>
* </ul>
*
* @param ocFile the file to be saved together with its parent hierarchy
* @param context Android context used for remote operations
*
* @return the same {@link OCFile} instance with a valid parent ID
*
* @param ocFile the file
* @param context the app context
* @return the parent file
* @throws RemoteOperationFailedException if a parent folder cannot be retrieved
* from the server
*/
public OCFile saveFileWithParent(OCFile ocFile, Context context) {
if (ocFile.getParentId() == 0 && !OCFile.ROOT_PATH.equals(ocFile.getRemotePath())) {
Log_OC.d(TAG, "saving file with parents: " + ocFile.getRemotePath());

String remotePath = ocFile.getRemotePath();
String parentPath = remotePath.substring(0, remotePath.lastIndexOf(ocFile.getFileName()));

OCFile parentFile = getFileByPath(parentPath);
OCFile returnFile;

if (parentFile == null) {
// remote request
ReadFileRemoteOperation operation = new ReadFileRemoteOperation(parentPath);
// TODO Deprecated
RemoteOperationResult result = operation.execute(getUser(), context);
if (result.isSuccess()) {
OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0));

returnFile = saveFileWithParent(remoteFolder, context);
Log_OC.d(TAG, "Parent not found locally, fetching: " + parentPath);

final var operation = new ReadFileRemoteOperation(parentPath);
final var result = operation.execute(getUser(), context);

if (result.isSuccess() && result.getData().get(0) instanceof RemoteFile remoteFile) {
OCFile folder = FileStorageUtils.fillOCFile(remoteFile);
Log_OC.d(TAG, "Fetched parent folder: " + folder);
returnFile = saveFileWithParent(folder, context);
} else {
Exception exception = result.getException();
String message = "Error during saving file with parents: " + ocFile.getRemotePath() + " / "
+ result.getLogMessage(context);

Log_OC.e(TAG, message);

if (exception != null) {
throw new RemoteOperationFailedException(message, exception);
} else {
throw new RemoteOperationFailedException(message);
}
}
} else {
Log_OC.d(TAG, "parent file exists, calling saveFileWithParent: " + ocFile.getRemotePath());
returnFile = saveFileWithParent(parentFile, context);
}

ocFile.setParentId(returnFile.getFileId());
long parentId = returnFile.getFileId();
Log_OC.d(TAG, "saving parent id of: " + ocFile.getRemotePath() + " with: " + parentId);
ocFile.setParentId(parentId);
saveFile(ocFile);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,6 @@ private void updatePredefinedStatus(ArbitraryDataProvider arbitraryDataProvider)

private RemoteOperationResult checkForChanges(OwnCloudClient client) {
mRemoteFolderChanged = true;
if (isMetadataSyncWorkerRunning) {
Log_OC.d(TAG, "Skipping eTag check since metadata worker already did");
return new RemoteOperationResult<>(ResultCode.OK);
}

RemoteOperationResult<?> result;
String remotePath = mLocalFolder.getRemotePath();

Expand All @@ -414,16 +409,18 @@ private RemoteOperationResult checkForChanges(OwnCloudClient client) {
result = new ReadFileRemoteOperation(remotePath).execute(client);

if (result.isSuccess()) {
if (!mIgnoreETag && result.getData().get(0) instanceof RemoteFile remoteFile) {
OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0));

if (!mIgnoreETag) {
// check if remote and local folder are different
String remoteFolderETag = remoteFile.getEtag();
String remoteFolderETag = remoteFolder.getEtag();
if (remoteFolderETag != null) {
String localFolderEtag = mLocalFolder.getEtag();
mRemoteFolderChanged = StringExtensionsKt.eTagChanged(remoteFolderETag, localFolderEtag);
Log_OC.d(
TAG,
"📂 eTag check\n" +
" Path: " + remoteFile.getRemotePath() + "\n" +
" Path: " + remoteFolder.getRemotePath() + "\n" +
" Local eTag: " + localFolderEtag + "\n" +
" Remote eTag: " + remoteFolderETag + "\n" +
" Changed: " + mRemoteFolderChanged
Expand Down Expand Up @@ -502,7 +499,7 @@ private void synchronizeData(List<Object> folderAndFiles) {
mLocalFolder = fileDataStorageManager.getFileByPath(mLocalFolder.getRemotePath());

if (mLocalFolder == null) {
Log_OC.d(TAG,"mLocalFolder cannot be null");
Log_OC.e(TAG,"mLocalFolder cannot be null");
return;
}

Expand All @@ -511,7 +508,7 @@ private void synchronizeData(List<Object> folderAndFiles) {
remoteFolder.setParentId(mLocalFolder.getParentId());
remoteFolder.setFileId(mLocalFolder.getFileId());

Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath() + " changed - starting update of local data ");
Log_OC.d(TAG, "Remote folder path: " + mLocalFolder.getRemotePath() + " changed - starting update of local data ");

List<OCFile> updatedFiles = new ArrayList<>(folderAndFiles.size() - 1);
mFilesToSyncContents.clear();
Expand Down
Loading