package com.owncloud.android.datamodel;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-
import android.accounts.Account;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import com.owncloud.android.MainApp;
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.lib.resources.files.FileUtils;
import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.lib.resources.shares.ShareType;
import com.owncloud.android.lib.resources.status.CapabilityBooleanType;
import com.owncloud.android.lib.resources.status.OCCapability;
import com.owncloud.android.utils.FileStorageUtils;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
public class FileDataStorageManager {
}
- public Vector<OCFile> getFolderContent(OCFile f/*, boolean onlyOnDevice*/) {
+ public Vector<OCFile> getFolderContent(OCFile f, boolean onlyOnDevice) {
if (f != null && f.isFolder() && f.getFileId() != -1) {
- // TODO Enable when "On Device" is recovered ?
- return getFolderContent(f.getFileId()/*, onlyOnDevice*/);
+ return getFolderContent(f.getFileId(), onlyOnDevice);
} else {
return new Vector<OCFile>();
}
- public Vector<OCFile> getFolderImages(OCFile folder/*, boolean onlyOnDevice*/) {
- Vector<OCFile> ret = new Vector<OCFile>();
+ public Vector<OCFile> getFolderImages(OCFile folder, boolean onlyOnDevice) {
+ Vector<OCFile> ret = new Vector<OCFile>();
if (folder != null) {
// TODO better implementation, filtering in the access to database instead of here
- // TODO Enable when "On Device" is recovered ?
- Vector<OCFile> tmp = getFolderContent(folder/*, onlyOnDevice*/);
- OCFile current = null;
+ Vector<OCFile> tmp = getFolderContent(folder, onlyOnDevice);
+ OCFile current = null;
for (int i=0; i<tmp.size(); i++) {
current = tmp.get(i);
if (current.isImage()) {
File localFolder = new File(localFolderPath);
if (localFolder.exists()) {
// stage 1: remove the local files already registered in the files database
- // TODO Enable when "On Device" is recovered ?
- Vector<OCFile> files = getFolderContent(folder.getFileId()/*, false*/);
+ Vector<OCFile> files = getFolderContent(folder.getFileId(), false);
if (files != null) {
for (OCFile file : files) {
if (file.isFolder()) {
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
- copied = copyFile(localFile, targetFile);
+ copied = FileStorageUtils.copyFile(localFile, targetFile);
}
Log_OC.d(TAG, "Local file COPIED : " + copied);
}
}
- private boolean copyFile(File src, File target) {
- boolean ret = true;
+ public void migrateStoredFiles(String srcPath, String dstPath) throws Exception {
+ Cursor c = null;
+ if (getContentResolver() != null) {
+ c = getContentResolver().query(ProviderTableMeta.CONTENT_URI_FILE,
+ null,
+ ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL",
+ null,
+ null);
+
+ } else {
+ try {
+ c = getContentProviderClient().query(ProviderTableMeta.CONTENT_URI_FILE,
+ new String[]{ProviderTableMeta._ID, ProviderTableMeta.FILE_STORAGE_PATH},
+ ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL",
+ null,
+ null);
+ } catch (RemoteException e) {
+ Log_OC.e(TAG, e.getMessage());
+ throw e;
+ }
+ }
+
+ ArrayList<ContentProviderOperation> operations =
+ new ArrayList<ContentProviderOperation>(c.getCount());
+ if (c.moveToFirst()) {
+ do {
+ ContentValues cv = new ContentValues();
+ long fileId = c.getLong(c.getColumnIndex(ProviderTableMeta._ID));
+ String oldFileStoragePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
+
+ if (oldFileStoragePath.startsWith(srcPath)) {
- InputStream in = null;
- OutputStream out = null;
+ cv.put(
+ ProviderTableMeta.FILE_STORAGE_PATH,
+ oldFileStoragePath.replaceFirst(srcPath, dstPath));
+ operations.add(
+ ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+ withValues(cv).
+ withSelection(
+ ProviderTableMeta._ID + "=?",
+ new String[]{String.valueOf(fileId)}
+ )
+ .build());
+ }
+
+ } while (c.moveToNext());
+ }
+ c.close();
+
+ /// 3. apply updates in batch
try {
- in = new FileInputStream(src);
- out = new FileOutputStream(target);
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0) {
- out.write(buf, 0, len);
- }
- } catch (IOException ex) {
- ret = false;
- } finally {
- if (in != null) try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace(System.err);
- }
- if (out != null) try {
- out.close();
- } catch (IOException e) {
- e.printStackTrace(System.err);
+ if (getContentResolver() != null) {
+ getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+
+ } else {
+ getContentProviderClient().applyBatch(operations);
}
- }
- return ret;
+ } catch (Exception e) {
+ throw e;
+ }
}
-
- private Vector<OCFile> getFolderContent(long parentId/*, boolean onlyOnDevice*/) {
+
+ private Vector<OCFile> getFolderContent(long parentId, boolean onlyOnDevice) {
Vector<OCFile> ret = new Vector<OCFile>();
if (c.moveToFirst()) {
do {
OCFile child = createFileInstance(c);
- // TODO Enable when "On Device" is recovered ?
- // if (child.isFolder() || !onlyOnDevice || onlyOnDevice && child.isDown()){
- ret.add(child);
- // }
+ if (child.isFolder() || !onlyOnDevice || onlyOnDevice && child.isDown()){
+ ret.add(child);
+ }
} while (c.moveToNext());
}
);
cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
- cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
+ cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
- if (shareExists(share.getIdRemoteShared())) {// for renamed files; no more delete and create
+ if (shareExists(share.getRemoteId())) {// for renamed files; no more delete and create
overriden = true;
if (getContentResolver() != null) {
getContentResolver().update(ProviderTableMeta.CONTENT_URI_SHARE, cv,
ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
- new String[]{String.valueOf(share.getIdRemoteShared())});
+ new String[]{String.valueOf(share.getRemoteId())});
} else {
try {
getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_SHARE,
cv, ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
- new String[]{String.valueOf(share.getIdRemoteShared())});
+ new String[]{String.valueOf(share.getRemoteId())});
} catch (RemoteException e) {
Log_OC.e(TAG,
"Fail to insert insert file to database "
}
+ /**
+ * Get first share bound to a file with a known path and given {@link ShareType}.
+ *
+ * @param path Path of the file.
+ * @param type Type of the share to get
+ * @param shareWith Target of the share. Ignored in type is {@link ShareType#PUBLIC_LINK}
+ * @return First {@OCShare} instance found in DB bound to the file in 'path'
+ */
public OCShare getFirstShareByPathAndType(String path, ShareType type, String shareWith) {
Cursor c = null;
+ if (shareWith == null) {
+ shareWith = "";
+ }
String selection = ProviderTableMeta.OCSHARES_PATH + "=? AND "
+ ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? AND "
- + ProviderTableMeta.OCSHARES_SHARE_WITH + "=? AND "
+ ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" ;
+ if (!ShareType.PUBLIC_LINK.equals(type)) {
+ selection += " AND " + ProviderTableMeta.OCSHARES_SHARE_WITH + "=?";
+ }
- String [] selectionArgs = new String[]{path, Integer.toString(type.getValue()),
- shareWith, mAccount.name};
+ String [] selectionArgs;
+ if (ShareType.PUBLIC_LINK.equals(type)) {
+ selectionArgs = new String[]{
+ path,
+ Integer.toString(type.getValue()),
+ mAccount.name
+ };
+ } else {
+ selectionArgs = new String[]{
+ path,
+ Integer.toString(type.getValue()),
+ mAccount.name,
+ shareWith
+ };
+ }
if (getContentResolver() != null) {
c = getContentResolver().query(
);
cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
- cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
+ cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
- if (shareExists(share.getIdRemoteShared())) {
+ if (shareExists(share.getRemoteId())) {
// updating an existing file
operations.add(
ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
withValues(cv).
withSelection(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
- new String[]{String.valueOf(share.getIdRemoteShared())})
+ new String[]{String.valueOf(share.getRemoteId())})
.build());
} else {
// adding a new file
// updateSharedFiles(sharedFiles);
}
+ public void removeSharesForFile(String remotePath) {
+ resetShareFlagInAFile(remotePath);
+ ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
+ operations = prepareRemoveSharesInFile(remotePath, operations);
+ // apply operations in batch
+ if (operations.size() > 0) {
+ Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
+ try {
+ if (getContentResolver() != null) {
+ getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+
+ } else {
+ getContentProviderClient().applyBatch(operations);
+ }
+
+ } catch (OperationApplicationException e) {
+ Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
+
+ } catch (RemoteException e) {
+ Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
+ }
+ }
+ }
+
public void saveSharesInFolder(ArrayList<OCShare> shares, OCFile folder) {
resetShareFlagsInFolder(folder);
);
cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
- cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
+ cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
// adding a new share resource
+ ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
String [] whereArgs = new String[]{ "", mAccount.name };
- // TODO Enable when "On Device" is recovered ?
- Vector<OCFile> files = getFolderContent(folder /*, false*/);
-
+ Vector<OCFile> files = getFolderContent(folder, false);
+
for (OCFile file : files) {
whereArgs[0] = file.getRemotePath();
preparedOperations.add(
}
public static void triggerMediaScan(String path) {
- Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
- intent.setData(Uri.fromFile(new File(path)));
- MainApp.getAppContext().sendBroadcast(intent);
+ if (path != null) {
+ Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+ intent.setData(Uri.fromFile(new File(path)));
+ MainApp.getAppContext().sendBroadcast(intent);
+ }
}
public void deleteFileInMediaScan(String path) {
if (c.moveToFirst()) {
capability = createCapabilityInstance(c);
+ } else {
+ capability = new OCCapability(); // return default with all UNKNOWN
}
c.close();
return capability;