FileDataStorageManager.java 92 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082
  1. /**
  2. * ownCloud Android client application
  3. *
  4. * Copyright (C) 2012 Bartek Przybylski
  5. * Copyright (C) 2015 ownCloud Inc.
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2,
  9. * as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. package com.owncloud.android.datamodel;
  21. import android.accounts.Account;
  22. import android.content.ContentProviderClient;
  23. import android.content.ContentProviderOperation;
  24. import android.content.ContentProviderResult;
  25. import android.content.ContentResolver;
  26. import android.content.ContentUris;
  27. import android.content.ContentValues;
  28. import android.content.Intent;
  29. import android.content.OperationApplicationException;
  30. import android.database.Cursor;
  31. import android.net.Uri;
  32. import android.os.RemoteException;
  33. import android.provider.MediaStore;
  34. import com.owncloud.android.MainApp;
  35. import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
  36. import com.owncloud.android.lib.common.utils.Log_OC;
  37. import com.owncloud.android.lib.resources.shares.OCShare;
  38. import com.owncloud.android.lib.resources.shares.ShareType;
  39. import com.owncloud.android.lib.resources.status.CapabilityBooleanType;
  40. import com.owncloud.android.lib.resources.status.OCCapability;
  41. import com.owncloud.android.utils.FileStorageUtils;
  42. import com.owncloud.android.utils.MimeType;
  43. import com.owncloud.android.utils.MimeTypeUtil;
  44. import java.io.File;
  45. import java.util.ArrayList;
  46. import java.util.Collection;
  47. import java.util.Collections;
  48. import java.util.HashSet;
  49. import java.util.Iterator;
  50. import java.util.List;
  51. import java.util.Set;
  52. import java.util.Vector;
  53. public class FileDataStorageManager {
  54. public static final int ROOT_PARENT_ID = 0;
  55. private ContentResolver mContentResolver;
  56. private ContentProviderClient mContentProviderClient;
  57. private Account mAccount;
  58. private static String TAG = FileDataStorageManager.class.getSimpleName();
  59. public FileDataStorageManager(Account account, ContentResolver cr) {
  60. mContentProviderClient = null;
  61. mContentResolver = cr;
  62. mAccount = account;
  63. }
  64. public FileDataStorageManager(Account account, ContentProviderClient cp) {
  65. mContentProviderClient = cp;
  66. mContentResolver = null;
  67. mAccount = account;
  68. }
  69. public void setAccount(Account account) {
  70. mAccount = account;
  71. }
  72. public Account getAccount() {
  73. return mAccount;
  74. }
  75. public ContentResolver getContentResolver() {
  76. return mContentResolver;
  77. }
  78. public ContentProviderClient getContentProviderClient() {
  79. return mContentProviderClient;
  80. }
  81. public OCFile getFileByPath(String path) {
  82. Cursor c = getFileCursorForValue(ProviderTableMeta.FILE_PATH, path);
  83. OCFile file = null;
  84. if (c.moveToFirst()) {
  85. file = createFileInstance(c);
  86. }
  87. c.close();
  88. if (file == null && OCFile.ROOT_PATH.equals(path)) {
  89. return createRootDir(); // root should always exist
  90. }
  91. return file;
  92. }
  93. public OCFile getFileById(long id) {
  94. Cursor c = getFileCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
  95. OCFile file = null;
  96. if (c.moveToFirst()) {
  97. file = createFileInstance(c);
  98. }
  99. c.close();
  100. return file;
  101. }
  102. public OCFile getFileByLocalPath(String path) {
  103. Cursor c = getFileCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path);
  104. OCFile file = null;
  105. if (c.moveToFirst()) {
  106. file = createFileInstance(c);
  107. }
  108. c.close();
  109. return file;
  110. }
  111. public boolean fileExists(long id) {
  112. return fileExists(ProviderTableMeta._ID, String.valueOf(id));
  113. }
  114. public boolean fileExists(String path) {
  115. return fileExists(ProviderTableMeta.FILE_PATH, path);
  116. }
  117. public Vector<OCFile> getFolderContent(OCFile f, boolean onlyOnDevice) {
  118. if (f != null && f.isFolder() && f.getFileId() != -1) {
  119. return getFolderContent(f.getFileId(), onlyOnDevice);
  120. } else {
  121. return new Vector<OCFile>();
  122. }
  123. }
  124. public Vector<OCFile> getFolderImages(OCFile folder, boolean onlyOnDevice) {
  125. Vector<OCFile> ret = new Vector<OCFile>();
  126. if (folder != null) {
  127. // TODO better implementation, filtering in the access to database instead of here
  128. Vector<OCFile> tmp = getFolderContent(folder, onlyOnDevice);
  129. OCFile current = null;
  130. for (int i=0; i<tmp.size(); i++) {
  131. current = tmp.get(i);
  132. if (MimeTypeUtil.isImage(current)) {
  133. ret.add(current);
  134. }
  135. }
  136. }
  137. return ret;
  138. }
  139. public boolean saveFile(OCFile file) {
  140. boolean overriden = false;
  141. ContentValues cv = new ContentValues();
  142. cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
  143. cv.put(
  144. ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
  145. file.getModificationTimestampAtLastSyncForData()
  146. );
  147. cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
  148. cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
  149. cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
  150. cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
  151. cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
  152. cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
  153. if (!file.isFolder())
  154. cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
  155. cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
  156. cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
  157. cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
  158. cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isFavorite() ? 1 : 0);
  159. cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
  160. cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
  161. cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
  162. cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
  163. cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
  164. cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
  165. cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
  166. cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
  167. cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict());
  168. boolean sameRemotePath = fileExists(file.getRemotePath());
  169. if (sameRemotePath ||
  170. fileExists(file.getFileId())) { // for renamed files; no more delete and create
  171. OCFile oldFile;
  172. if (sameRemotePath) {
  173. oldFile = getFileByPath(file.getRemotePath());
  174. file.setFileId(oldFile.getFileId());
  175. } else {
  176. oldFile = getFileById(file.getFileId());
  177. }
  178. overriden = true;
  179. if (getContentResolver() != null) {
  180. getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
  181. ProviderTableMeta._ID + "=?",
  182. new String[]{String.valueOf(file.getFileId())});
  183. } else {
  184. try {
  185. getContentProviderClient().update(ProviderTableMeta.CONTENT_URI,
  186. cv, ProviderTableMeta._ID + "=?",
  187. new String[]{String.valueOf(file.getFileId())});
  188. } catch (RemoteException e) {
  189. Log_OC.e(TAG,
  190. "Fail to insert insert file to database "
  191. + e.getMessage());
  192. }
  193. }
  194. } else {
  195. Uri result_uri = null;
  196. if (getContentResolver() != null) {
  197. result_uri = getContentResolver().insert(
  198. ProviderTableMeta.CONTENT_URI_FILE, cv);
  199. } else {
  200. try {
  201. result_uri = getContentProviderClient().insert(
  202. ProviderTableMeta.CONTENT_URI_FILE, cv);
  203. } catch (RemoteException e) {
  204. Log_OC.e(TAG,
  205. "Fail to insert insert file to database "
  206. + e.getMessage());
  207. }
  208. }
  209. if (result_uri != null) {
  210. long new_id = Long.parseLong(result_uri.getPathSegments()
  211. .get(1));
  212. file.setFileId(new_id);
  213. }
  214. }
  215. return overriden;
  216. }
  217. public void saveNewFile(OCFile newFile) {
  218. String remoteParentPath = new File(newFile.getRemotePath()).getParent();
  219. remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ?
  220. remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
  221. OCFile parent = getFileByPath(remoteParentPath);
  222. if (parent != null) {
  223. newFile.setParentId(parent.getFileId());
  224. saveFile(newFile);
  225. } else {
  226. throw new IllegalArgumentException("Saving a new file in an unexisting folder");
  227. }
  228. }
  229. /**
  230. * Inserts or updates the list of files contained in a given folder.
  231. * <p/>
  232. * CALLER IS THE RESPONSIBLE FOR GRANTING RIGHT UPDATE OF INFORMATION, NOT THIS METHOD.
  233. * HERE ONLY DATA CONSISTENCY SHOULD BE GRANTED
  234. *
  235. * @param folder
  236. * @param updatedFiles
  237. * @param filesToRemove
  238. */
  239. public void saveFolder(
  240. OCFile folder, Collection<OCFile> updatedFiles, Collection<OCFile> filesToRemove
  241. ) {
  242. Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size()
  243. + " children and " + filesToRemove.size() + " files to remove");
  244. ArrayList<ContentProviderOperation> operations =
  245. new ArrayList<ContentProviderOperation>(updatedFiles.size());
  246. // prepare operations to insert or update files to save in the given folder
  247. for (OCFile file : updatedFiles) {
  248. ContentValues cv = new ContentValues();
  249. cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
  250. cv.put(
  251. ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
  252. file.getModificationTimestampAtLastSyncForData()
  253. );
  254. cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
  255. cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
  256. cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
  257. cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
  258. //cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
  259. cv.put(ProviderTableMeta.FILE_PARENT, folder.getFileId());
  260. cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
  261. if (!file.isFolder()) {
  262. cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
  263. }
  264. cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
  265. cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
  266. cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
  267. cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isFavorite() ? 1 : 0);
  268. cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
  269. cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
  270. cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
  271. cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
  272. cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
  273. cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
  274. cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
  275. cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
  276. cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict());
  277. boolean existsByPath = fileExists(file.getRemotePath());
  278. if (existsByPath || fileExists(file.getFileId())) {
  279. // updating an existing file
  280. operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
  281. withValues(cv).
  282. withSelection(ProviderTableMeta._ID + "=?",
  283. new String[]{String.valueOf(file.getFileId())})
  284. .build());
  285. } else {
  286. // adding a new file
  287. operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).
  288. withValues(cv).build());
  289. }
  290. }
  291. // prepare operations to remove files in the given folder
  292. String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " +
  293. ProviderTableMeta.FILE_PATH + "=?";
  294. String [] whereArgs = null;
  295. for (OCFile file : filesToRemove) {
  296. if (file.getParentId() == folder.getFileId()) {
  297. whereArgs = new String[]{mAccount.name, file.getRemotePath()};
  298. if (file.isFolder()) {
  299. operations.add(ContentProviderOperation.newDelete(
  300. ContentUris.withAppendedId(
  301. ProviderTableMeta.CONTENT_URI_DIR, file.getFileId()
  302. )
  303. ).withSelection(where, whereArgs).build());
  304. File localFolder =
  305. new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
  306. if (localFolder.exists()) {
  307. removeLocalFolder(localFolder);
  308. }
  309. } else {
  310. operations.add(ContentProviderOperation.newDelete(
  311. ContentUris.withAppendedId(
  312. ProviderTableMeta.CONTENT_URI_FILE, file.getFileId()
  313. )
  314. ).withSelection(where, whereArgs).build());
  315. if (file.isDown()) {
  316. String path = file.getStoragePath();
  317. new File(path).delete();
  318. triggerMediaScan(path); // notify MediaScanner about removed file
  319. }
  320. }
  321. }
  322. }
  323. // update metadata of folder
  324. ContentValues cv = new ContentValues();
  325. cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp());
  326. cv.put(
  327. ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
  328. folder.getModificationTimestampAtLastSyncForData()
  329. );
  330. cv.put(ProviderTableMeta.FILE_CREATION, folder.getCreationTimestamp());
  331. cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0);
  332. cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimetype());
  333. cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
  334. cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
  335. cv.put(ProviderTableMeta.FILE_PATH, folder.getRemotePath());
  336. cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
  337. cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, folder.getLastSyncDateForProperties());
  338. cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
  339. cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, folder.isFavorite() ? 1 : 0);
  340. cv.put(ProviderTableMeta.FILE_ETAG, folder.getEtag());
  341. cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, folder.isSharedViaLink() ? 1 : 0);
  342. cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, folder.isSharedWithSharee() ? 1 : 0);
  343. cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, folder.getPublicLink());
  344. cv.put(ProviderTableMeta.FILE_PERMISSIONS, folder.getPermissions());
  345. cv.put(ProviderTableMeta.FILE_REMOTE_ID, folder.getRemoteId());
  346. operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
  347. withValues(cv).
  348. withSelection(ProviderTableMeta._ID + "=?",
  349. new String[]{String.valueOf(folder.getFileId())})
  350. .build());
  351. // apply operations in batch
  352. ContentProviderResult[] results = null;
  353. Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
  354. try {
  355. if (getContentResolver() != null) {
  356. results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
  357. } else {
  358. results = getContentProviderClient().applyBatch(operations);
  359. }
  360. } catch (OperationApplicationException e) {
  361. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  362. } catch (RemoteException e) {
  363. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  364. }
  365. // update new id in file objects for insertions
  366. if (results != null) {
  367. long newId;
  368. Iterator<OCFile> filesIt = updatedFiles.iterator();
  369. OCFile file = null;
  370. for (int i = 0; i < results.length; i++) {
  371. if (filesIt.hasNext()) {
  372. file = filesIt.next();
  373. } else {
  374. file = null;
  375. }
  376. if (results[i].uri != null) {
  377. newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
  378. //updatedFiles.get(i).setFileId(newId);
  379. if (file != null) {
  380. file.setFileId(newId);
  381. }
  382. }
  383. }
  384. }
  385. }
  386. public boolean removeFile(OCFile file, boolean removeDBData, boolean removeLocalCopy) {
  387. boolean success = false;
  388. if (file != null) {
  389. if (file.isFolder()) {
  390. success = removeFolder(file, removeDBData, removeLocalCopy);
  391. } else {
  392. if (removeDBData) {
  393. //Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE,
  394. // ""+file.getFileId());
  395. Uri file_uri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE,
  396. file.getFileId());
  397. String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " +
  398. ProviderTableMeta.FILE_PATH + "=?";
  399. String[] whereArgs = new String[]{mAccount.name, file.getRemotePath()};
  400. int deleted = 0;
  401. if (getContentProviderClient() != null) {
  402. try {
  403. deleted = getContentProviderClient().delete(file_uri, where, whereArgs);
  404. } catch (RemoteException e) {
  405. e.printStackTrace();
  406. }
  407. } else {
  408. deleted = getContentResolver().delete(file_uri, where, whereArgs);
  409. }
  410. success &= (deleted > 0);
  411. }
  412. String localPath = file.getStoragePath();
  413. if (removeLocalCopy && file.isDown() && localPath != null && success) {
  414. success = new File(localPath).delete();
  415. if (success) {
  416. deleteFileInMediaScan(localPath);
  417. }
  418. if (!removeDBData && success) {
  419. // maybe unnecessary, but should be checked TODO remove if unnecessary
  420. file.setStoragePath(null);
  421. saveFile(file);
  422. saveConflict(file, null);
  423. }
  424. }
  425. }
  426. }
  427. return success;
  428. }
  429. public boolean removeFolder(OCFile folder, boolean removeDBData, boolean removeLocalContent) {
  430. boolean success = false;
  431. if (folder != null && folder.isFolder()) {
  432. if (removeDBData && folder.getFileId() != -1) {
  433. success = removeFolderInDb(folder);
  434. }
  435. if (removeLocalContent && success) {
  436. success = removeLocalFolder(folder);
  437. }
  438. }
  439. return success;
  440. }
  441. private boolean removeFolderInDb(OCFile folder) {
  442. Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, "" +
  443. folder.getFileId()); // URI for recursive deletion
  444. String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " +
  445. ProviderTableMeta.FILE_PATH + "=?";
  446. String [] whereArgs = new String[]{mAccount.name, folder.getRemotePath()};
  447. int deleted = 0;
  448. if (getContentProviderClient() != null) {
  449. try {
  450. deleted = getContentProviderClient().delete(folder_uri, where, whereArgs);
  451. } catch (RemoteException e) {
  452. e.printStackTrace();
  453. }
  454. } else {
  455. deleted = getContentResolver().delete(folder_uri, where, whereArgs);
  456. }
  457. return deleted > 0;
  458. }
  459. private boolean removeLocalFolder(OCFile folder) {
  460. boolean success = true;
  461. String localFolderPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, folder);
  462. File localFolder = new File(localFolderPath);
  463. if (localFolder.exists()) {
  464. // stage 1: remove the local files already registered in the files database
  465. Vector<OCFile> files = getFolderContent(folder.getFileId(), false);
  466. if (files != null) {
  467. for (OCFile file : files) {
  468. if (file.isFolder()) {
  469. success &= removeLocalFolder(file);
  470. } else {
  471. if (file.isDown()) {
  472. File localFile = new File(file.getStoragePath());
  473. success &= localFile.delete();
  474. if (success) {
  475. // notify MediaScanner about removed file
  476. deleteFileInMediaScan(file.getStoragePath());
  477. file.setStoragePath(null);
  478. saveFile(file);
  479. }
  480. }
  481. }
  482. }
  483. }
  484. // stage 2: remove the folder itself and any local file inside out of sync;
  485. // for instance, after clearing the app cache or reinstalling
  486. success &= removeLocalFolder(localFolder);
  487. }
  488. return success;
  489. }
  490. private boolean removeLocalFolder(File localFolder) {
  491. boolean success = true;
  492. File[] localFiles = localFolder.listFiles();
  493. if (localFiles != null) {
  494. for (File localFile : localFiles) {
  495. if (localFile.isDirectory()) {
  496. success &= removeLocalFolder(localFile);
  497. } else {
  498. String path = localFile.getAbsolutePath();
  499. success &= localFile.delete();
  500. }
  501. }
  502. }
  503. success &= localFolder.delete();
  504. return success;
  505. }
  506. /**
  507. * Updates database and file system for a file or folder that was moved to a different location.
  508. *
  509. * TODO explore better (faster) implementations
  510. * TODO throw exceptions up !
  511. */
  512. public void moveLocalFile(OCFile file, String targetPath, String targetParentPath) {
  513. if (file != null && file.fileExists() && !OCFile.ROOT_PATH.equals(file.getFileName())) {
  514. OCFile targetParent = getFileByPath(targetParentPath);
  515. if (targetParent == null) {
  516. throw new IllegalStateException(
  517. "Parent folder of the target path does not exist!!");
  518. }
  519. /// 1. get all the descendants of the moved element in a single QUERY
  520. Cursor c = null;
  521. if (getContentProviderClient() != null) {
  522. try {
  523. c = getContentProviderClient().query(
  524. ProviderTableMeta.CONTENT_URI,
  525. null,
  526. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  527. ProviderTableMeta.FILE_PATH + " LIKE ? ",
  528. new String[]{
  529. mAccount.name,
  530. file.getRemotePath() + "%"
  531. },
  532. ProviderTableMeta.FILE_PATH + " ASC "
  533. );
  534. } catch (RemoteException e) {
  535. Log_OC.e(TAG, e.getMessage());
  536. }
  537. } else {
  538. c = getContentResolver().query(
  539. ProviderTableMeta.CONTENT_URI,
  540. null,
  541. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  542. ProviderTableMeta.FILE_PATH + " LIKE ? ",
  543. new String[]{
  544. mAccount.name,
  545. file.getRemotePath() + "%"
  546. },
  547. ProviderTableMeta.FILE_PATH + " ASC "
  548. );
  549. }
  550. /// 2. prepare a batch of update operations to change all the descendants
  551. ArrayList<ContentProviderOperation> operations =
  552. new ArrayList<ContentProviderOperation>(c.getCount());
  553. String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name);
  554. List<String> originalPathsToTriggerMediaScan = new ArrayList<String>();
  555. List<String> newPathsToTriggerMediaScan = new ArrayList<String>();
  556. if (c.moveToFirst()) {
  557. int lengthOfOldPath = file.getRemotePath().length();
  558. int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath;
  559. do {
  560. ContentValues cv = new ContentValues(); // keep construction in the loop
  561. OCFile child = createFileInstance(c);
  562. cv.put(
  563. ProviderTableMeta.FILE_PATH,
  564. targetPath + child.getRemotePath().substring(lengthOfOldPath)
  565. );
  566. if (child.getStoragePath() != null &&
  567. child.getStoragePath().startsWith(defaultSavePath)) {
  568. // update link to downloaded content - but local move is not done here!
  569. String targetLocalPath = defaultSavePath + targetPath +
  570. child.getStoragePath().substring(lengthOfOldStoragePath);
  571. cv.put(ProviderTableMeta.FILE_STORAGE_PATH, targetLocalPath);
  572. originalPathsToTriggerMediaScan.add(child.getStoragePath());
  573. newPathsToTriggerMediaScan.add(targetLocalPath);
  574. }
  575. if (child.getRemotePath().equals(file.getRemotePath())) {
  576. cv.put(
  577. ProviderTableMeta.FILE_PARENT,
  578. targetParent.getFileId()
  579. );
  580. }
  581. operations.add(
  582. ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
  583. withValues(cv).
  584. withSelection(
  585. ProviderTableMeta._ID + "=?",
  586. new String[]{String.valueOf(child.getFileId())}
  587. )
  588. .build());
  589. } while (c.moveToNext());
  590. }
  591. c.close();
  592. /// 3. apply updates in batch
  593. try {
  594. if (getContentResolver() != null) {
  595. getContentResolver().applyBatch(MainApp.getAuthority(), operations);
  596. } else {
  597. getContentProviderClient().applyBatch(operations);
  598. }
  599. } catch (Exception e) {
  600. Log_OC.e(TAG, "Fail to update " + file.getFileId() + " and descendants in database",
  601. e);
  602. }
  603. /// 4. move in local file system
  604. String originalLocalPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, file);
  605. String targetLocalPath = defaultSavePath + targetPath;
  606. File localFile = new File(originalLocalPath);
  607. boolean renamed = false;
  608. if (localFile.exists()) {
  609. File targetFile = new File(targetLocalPath);
  610. File targetFolder = targetFile.getParentFile();
  611. if (!targetFolder.exists()) {
  612. targetFolder.mkdirs();
  613. }
  614. renamed = localFile.renameTo(targetFile);
  615. }
  616. if (renamed) {
  617. Iterator<String> it = originalPathsToTriggerMediaScan.iterator();
  618. while (it.hasNext()) {
  619. // Notify MediaScanner about removed file
  620. deleteFileInMediaScan(it.next());
  621. }
  622. it = newPathsToTriggerMediaScan.iterator();
  623. while (it.hasNext()) {
  624. // Notify MediaScanner about new file/folder
  625. triggerMediaScan(it.next());
  626. }
  627. }
  628. }
  629. }
  630. public void copyLocalFile(OCFile file, String targetPath) {
  631. if (file != null && file.fileExists() && !OCFile.ROOT_PATH.equals(file.getFileName())) {
  632. String localPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, file);
  633. File localFile = new File(localPath);
  634. boolean copied = false;
  635. String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name);
  636. if (localFile.exists()) {
  637. File targetFile = new File(defaultSavePath + targetPath);
  638. File targetFolder = targetFile.getParentFile();
  639. if (!targetFolder.exists()) {
  640. targetFolder.mkdirs();
  641. }
  642. copied = FileStorageUtils.copyFile(localFile, targetFile);
  643. }
  644. Log_OC.d(TAG, "Local file COPIED : " + copied);
  645. }
  646. }
  647. public void migrateStoredFiles(String srcPath, String dstPath) throws Exception {
  648. Cursor c = null;
  649. if (getContentResolver() != null) {
  650. c = getContentResolver().query(ProviderTableMeta.CONTENT_URI_FILE,
  651. null,
  652. ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL",
  653. null,
  654. null);
  655. } else {
  656. try {
  657. c = getContentProviderClient().query(ProviderTableMeta.CONTENT_URI_FILE,
  658. new String[]{ProviderTableMeta._ID, ProviderTableMeta.FILE_STORAGE_PATH},
  659. ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL",
  660. null,
  661. null);
  662. } catch (RemoteException e) {
  663. Log_OC.e(TAG, e.getMessage());
  664. throw e;
  665. }
  666. }
  667. ArrayList<ContentProviderOperation> operations =
  668. new ArrayList<ContentProviderOperation>(c.getCount());
  669. if (c.moveToFirst()) {
  670. do {
  671. ContentValues cv = new ContentValues();
  672. long fileId = c.getLong(c.getColumnIndex(ProviderTableMeta._ID));
  673. String oldFileStoragePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
  674. if (oldFileStoragePath.startsWith(srcPath)) {
  675. cv.put(
  676. ProviderTableMeta.FILE_STORAGE_PATH,
  677. oldFileStoragePath.replaceFirst(srcPath, dstPath));
  678. operations.add(
  679. ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
  680. withValues(cv).
  681. withSelection(
  682. ProviderTableMeta._ID + "=?",
  683. new String[]{String.valueOf(fileId)}
  684. )
  685. .build());
  686. }
  687. } while (c.moveToNext());
  688. }
  689. c.close();
  690. /// 3. apply updates in batch
  691. if (getContentResolver() != null) {
  692. getContentResolver().applyBatch(MainApp.getAuthority(), operations);
  693. } else {
  694. getContentProviderClient().applyBatch(operations);
  695. }
  696. }
  697. private Vector<OCFile> getFolderContent(long parentId, boolean onlyOnDevice) {
  698. Vector<OCFile> ret = new Vector<OCFile>();
  699. Uri req_uri = Uri.withAppendedPath(
  700. ProviderTableMeta.CONTENT_URI_DIR,
  701. String.valueOf(parentId));
  702. Cursor c = null;
  703. if (getContentProviderClient() != null) {
  704. try {
  705. c = getContentProviderClient().query(req_uri, null,
  706. ProviderTableMeta.FILE_PARENT + "=?",
  707. new String[]{String.valueOf(parentId)}, null);
  708. } catch (RemoteException e) {
  709. Log_OC.e(TAG, e.getMessage());
  710. return ret;
  711. }
  712. } else {
  713. c = getContentResolver().query(req_uri, null,
  714. ProviderTableMeta.FILE_PARENT + "=?",
  715. new String[]{String.valueOf(parentId)}, null);
  716. }
  717. if (c.moveToFirst()) {
  718. do {
  719. OCFile child = createFileInstance(c);
  720. if (child.isFolder() || !onlyOnDevice || onlyOnDevice && child.isDown()){
  721. ret.add(child);
  722. }
  723. } while (c.moveToNext());
  724. }
  725. c.close();
  726. Collections.sort(ret);
  727. return ret;
  728. }
  729. private OCFile createRootDir() {
  730. OCFile file = new OCFile(OCFile.ROOT_PATH);
  731. file.setMimetype(MimeType.DIRECTORY);
  732. file.setParentId(FileDataStorageManager.ROOT_PARENT_ID);
  733. saveFile(file);
  734. return file;
  735. }
  736. private boolean fileExists(String cmp_key, String value) {
  737. Cursor c;
  738. if (getContentResolver() != null) {
  739. c = getContentResolver()
  740. .query(ProviderTableMeta.CONTENT_URI,
  741. null,
  742. cmp_key + "=? AND "
  743. + ProviderTableMeta.FILE_ACCOUNT_OWNER
  744. + "=?",
  745. new String[]{value, mAccount.name}, null);
  746. } else {
  747. try {
  748. c = getContentProviderClient().query(
  749. ProviderTableMeta.CONTENT_URI,
  750. null,
  751. cmp_key + "=? AND "
  752. + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
  753. new String[]{value, mAccount.name}, null);
  754. } catch (RemoteException e) {
  755. Log_OC.e(TAG,
  756. "Couldn't determine file existance, assuming non existance: "
  757. + e.getMessage());
  758. return false;
  759. }
  760. }
  761. boolean retval = c.moveToFirst();
  762. c.close();
  763. return retval;
  764. }
  765. private Cursor getFileCursorForValue(String key, String value) {
  766. Cursor c = null;
  767. if (getContentResolver() != null) {
  768. c = getContentResolver()
  769. .query(ProviderTableMeta.CONTENT_URI,
  770. null,
  771. key + "=? AND "
  772. + ProviderTableMeta.FILE_ACCOUNT_OWNER
  773. + "=?",
  774. new String[]{value, mAccount.name}, null);
  775. } else {
  776. try {
  777. c = getContentProviderClient().query(
  778. ProviderTableMeta.CONTENT_URI,
  779. null,
  780. key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER
  781. + "=?", new String[]{value, mAccount.name},
  782. null);
  783. } catch (RemoteException e) {
  784. Log_OC.e(TAG, "Could not get file details: " + e.getMessage());
  785. c = null;
  786. }
  787. }
  788. return c;
  789. }
  790. private OCFile createFileInstance(Cursor c) {
  791. OCFile file = null;
  792. if (c != null) {
  793. file = new OCFile(c.getString(c
  794. .getColumnIndex(ProviderTableMeta.FILE_PATH)));
  795. file.setFileId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
  796. file.setParentId(c.getLong(c
  797. .getColumnIndex(ProviderTableMeta.FILE_PARENT)));
  798. file.setMimetype(c.getString(c
  799. .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
  800. if (!file.isFolder()) {
  801. file.setStoragePath(c.getString(c
  802. .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
  803. if (file.getStoragePath() == null) {
  804. // try to find existing file and bind it with current account;
  805. // with the current update of SynchronizeFolderOperation, this won't be
  806. // necessary anymore after a full synchronization of the account
  807. File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
  808. if (f.exists()) {
  809. file.setStoragePath(f.getAbsolutePath());
  810. file.setLastSyncDateForData(f.lastModified());
  811. }
  812. }
  813. }
  814. file.setFileLength(c.getLong(c
  815. .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)));
  816. file.setCreationTimestamp(c.getLong(c
  817. .getColumnIndex(ProviderTableMeta.FILE_CREATION)));
  818. file.setModificationTimestamp(c.getLong(c
  819. .getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
  820. file.setModificationTimestampAtLastSyncForData(c.getLong(c
  821. .getColumnIndex(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA)));
  822. file.setLastSyncDateForProperties(c.getLong(c
  823. .getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
  824. file.setLastSyncDateForData(c.getLong(c.
  825. getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA)));
  826. file.setFavorite(c.getInt(
  827. c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
  828. file.setEtag(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG)));
  829. file.setShareViaLink(c.getInt(
  830. c.getColumnIndex(ProviderTableMeta.FILE_SHARED_VIA_LINK)) == 1 ? true : false);
  831. file.setShareWithSharee(c.getInt(
  832. c.getColumnIndex(ProviderTableMeta.FILE_SHARED_WITH_SHAREE)) == 1 ? true : false);
  833. file.setPublicLink(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PUBLIC_LINK)));
  834. file.setPermissions(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PERMISSIONS)));
  835. file.setRemoteId(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_REMOTE_ID)));
  836. file.setNeedsUpdateThumbnail(c.getInt(
  837. c.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1 ? true : false);
  838. file.setDownloading(c.getInt(
  839. c.getColumnIndex(ProviderTableMeta.FILE_IS_DOWNLOADING)) == 1 ? true : false);
  840. file.setEtagInConflict(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG_IN_CONFLICT)));
  841. }
  842. return file;
  843. }
  844. // Methods for Shares
  845. public boolean saveShare(OCShare share) {
  846. boolean overriden = false;
  847. ContentValues cv = new ContentValues();
  848. cv.put(ProviderTableMeta.OCSHARES_FILE_SOURCE, share.getFileSource());
  849. cv.put(ProviderTableMeta.OCSHARES_ITEM_SOURCE, share.getItemSource());
  850. cv.put(ProviderTableMeta.OCSHARES_SHARE_TYPE, share.getShareType().getValue());
  851. cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH, share.getShareWith());
  852. cv.put(ProviderTableMeta.OCSHARES_PATH, share.getPath());
  853. cv.put(ProviderTableMeta.OCSHARES_PERMISSIONS, share.getPermissions());
  854. cv.put(ProviderTableMeta.OCSHARES_SHARED_DATE, share.getSharedDate());
  855. cv.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE, share.getExpirationDate());
  856. cv.put(ProviderTableMeta.OCSHARES_TOKEN, share.getToken());
  857. cv.put(
  858. ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME,
  859. share.getSharedWithDisplayName()
  860. );
  861. cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
  862. cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
  863. cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
  864. cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
  865. if (shareExistsForRemoteId(share.getRemoteId())) {// for renamed files; no more delete and create
  866. overriden = true;
  867. if (getContentResolver() != null) {
  868. getContentResolver().update(ProviderTableMeta.CONTENT_URI_SHARE, cv,
  869. ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
  870. new String[]{String.valueOf(share.getRemoteId())});
  871. } else {
  872. try {
  873. getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_SHARE,
  874. cv, ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
  875. new String[]{String.valueOf(share.getRemoteId())});
  876. } catch (RemoteException e) {
  877. Log_OC.e(TAG,
  878. "Fail to insert insert file to database "
  879. + e.getMessage());
  880. }
  881. }
  882. } else {
  883. Uri result_uri = null;
  884. if (getContentResolver() != null) {
  885. result_uri = getContentResolver().insert(
  886. ProviderTableMeta.CONTENT_URI_SHARE, cv);
  887. } else {
  888. try {
  889. result_uri = getContentProviderClient().insert(
  890. ProviderTableMeta.CONTENT_URI_SHARE, cv);
  891. } catch (RemoteException e) {
  892. Log_OC.e(TAG,
  893. "Fail to insert insert file to database "
  894. + e.getMessage());
  895. }
  896. }
  897. if (result_uri != null) {
  898. long new_id = Long.parseLong(result_uri.getPathSegments()
  899. .get(1));
  900. share.setId(new_id);
  901. }
  902. }
  903. return overriden;
  904. }
  905. /**
  906. * Retrieves an stored {@link OCShare} given its id.
  907. *
  908. * @param id Identifier.
  909. * @return Stored {@link OCShare} given its id.
  910. */
  911. public OCShare getShareById(long id) {
  912. OCShare share = null;
  913. Cursor c = getShareCursorForValue(
  914. ProviderTableMeta._ID,
  915. String.valueOf(id)
  916. );
  917. if (c != null) {
  918. if (c.moveToFirst()) {
  919. share = createShareInstance(c);
  920. }
  921. c.close();
  922. }
  923. return share;
  924. }
  925. /**
  926. * Checks the existance of an stored {@link OCShare} matching the given remote id (not to be confused with
  927. * the local id) in the current account.
  928. *
  929. * @param remoteId Remote of the share in the server.
  930. * @return 'True' if a matching {@link OCShare} is stored in the current account.
  931. */
  932. private boolean shareExistsForRemoteId(long remoteId) {
  933. return shareExistsForValue(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, String.valueOf(remoteId));
  934. }
  935. /**
  936. * Checks the existance of an stored {@link OCShare} in the current account
  937. * matching a given column and a value for that column
  938. *
  939. * @param key Name of the column to match.
  940. * @param value Value of the column to match.
  941. * @return 'True' if a matching {@link OCShare} is stored in the current account.
  942. */
  943. private boolean shareExistsForValue(String key, String value) {
  944. Cursor c = getShareCursorForValue(key, value);
  945. boolean retval = c.moveToFirst();
  946. c.close();
  947. return retval;
  948. }
  949. /**
  950. * Gets a {@link Cursor} for an stored {@link OCShare} in the current account
  951. * matching a given column and a value for that column
  952. *
  953. * @param key Name of the column to match.
  954. * @param value Value of the column to match.
  955. * @return 'True' if a matching {@link OCShare} is stored in the current account.
  956. */
  957. private Cursor getShareCursorForValue(String key, String value) {
  958. Cursor c;
  959. if (getContentResolver() != null) {
  960. c = getContentResolver()
  961. .query(ProviderTableMeta.CONTENT_URI_SHARE,
  962. null,
  963. key + "=? AND "
  964. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?",
  965. new String[]{value, mAccount.name},
  966. null
  967. );
  968. } else {
  969. try {
  970. c = getContentProviderClient().query(
  971. ProviderTableMeta.CONTENT_URI_SHARE,
  972. null,
  973. key + "=? AND "
  974. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?",
  975. new String[]{value, mAccount.name},
  976. null
  977. );
  978. } catch (RemoteException e) {
  979. Log_OC.w(TAG,
  980. "Could not get details, assuming share does not exist: "+ e.getMessage());
  981. c = null;
  982. }
  983. }
  984. return c;
  985. }
  986. /**
  987. * Get first share bound to a file with a known path and given {@link ShareType}.
  988. *
  989. * @param path Path of the file.
  990. * @param type Type of the share to get
  991. * @param shareWith Target of the share. Ignored in type is {@link ShareType#PUBLIC_LINK}
  992. * @return First {@OCShare} instance found in DB bound to the file in 'path'
  993. */
  994. public OCShare getFirstShareByPathAndType(String path, ShareType type, String shareWith) {
  995. Cursor c = null;
  996. if (shareWith == null) {
  997. shareWith = "";
  998. }
  999. String selection = ProviderTableMeta.OCSHARES_PATH + "=? AND "
  1000. + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? AND "
  1001. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" ;
  1002. if (!ShareType.PUBLIC_LINK.equals(type)) {
  1003. selection += " AND " + ProviderTableMeta.OCSHARES_SHARE_WITH + "=?";
  1004. }
  1005. String [] selectionArgs;
  1006. if (ShareType.PUBLIC_LINK.equals(type)) {
  1007. selectionArgs = new String[]{
  1008. path,
  1009. Integer.toString(type.getValue()),
  1010. mAccount.name
  1011. };
  1012. } else {
  1013. selectionArgs = new String[]{
  1014. path,
  1015. Integer.toString(type.getValue()),
  1016. mAccount.name,
  1017. shareWith
  1018. };
  1019. }
  1020. if (getContentResolver() != null) {
  1021. c = getContentResolver().query(
  1022. ProviderTableMeta.CONTENT_URI_SHARE,
  1023. null,
  1024. selection, selectionArgs,
  1025. null);
  1026. } else {
  1027. try {
  1028. c = getContentProviderClient().query(
  1029. ProviderTableMeta.CONTENT_URI_SHARE,
  1030. null,
  1031. selection, selectionArgs,
  1032. null);
  1033. } catch (RemoteException e) {
  1034. Log_OC.e(TAG, "Could not get file details: " + e.getMessage());
  1035. c = null;
  1036. }
  1037. }
  1038. OCShare share = null;
  1039. if (c.moveToFirst()) {
  1040. share = createShareInstance(c);
  1041. }
  1042. c.close();
  1043. return share;
  1044. }
  1045. private OCShare createShareInstance(Cursor c) {
  1046. OCShare share = null;
  1047. if (c != null) {
  1048. share = new OCShare(c.getString(c
  1049. .getColumnIndex(ProviderTableMeta.OCSHARES_PATH)));
  1050. share.setId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
  1051. share.setFileSource(c.getLong(c
  1052. .getColumnIndex(ProviderTableMeta.OCSHARES_ITEM_SOURCE)));
  1053. share.setShareType(ShareType.fromValue(c.getInt(c
  1054. .getColumnIndex(ProviderTableMeta.OCSHARES_SHARE_TYPE))));
  1055. share.setShareWith(c.getString(c
  1056. .getColumnIndex(ProviderTableMeta.OCSHARES_SHARE_WITH)));
  1057. share.setPermissions(c.getInt(c
  1058. .getColumnIndex(ProviderTableMeta.OCSHARES_PERMISSIONS)));
  1059. share.setSharedDate(c.getLong(c
  1060. .getColumnIndex(ProviderTableMeta.OCSHARES_SHARED_DATE)));
  1061. share.setExpirationDate(c.getLong(c
  1062. .getColumnIndex(ProviderTableMeta.OCSHARES_EXPIRATION_DATE)));
  1063. share.setToken(c.getString(c
  1064. .getColumnIndex(ProviderTableMeta.OCSHARES_TOKEN)));
  1065. share.setSharedWithDisplayName(c.getString(c
  1066. .getColumnIndex(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME)));
  1067. share.setIsFolder(c.getInt(
  1068. c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_DIRECTORY)) == 1);
  1069. share.setUserId(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_USER_ID)));
  1070. share.setIdRemoteShared(c.getLong(
  1071. c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED)));
  1072. }
  1073. return share;
  1074. }
  1075. private void resetShareFlagsInAllFiles() {
  1076. ContentValues cv = new ContentValues();
  1077. cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, false);
  1078. cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false);
  1079. cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
  1080. String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?";
  1081. String[] whereArgs = new String[]{mAccount.name};
  1082. if (getContentResolver() != null) {
  1083. getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
  1084. } else {
  1085. try {
  1086. getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where,
  1087. whereArgs);
  1088. } catch (RemoteException e) {
  1089. Log_OC.e(TAG, "Exception in resetShareFlagsInAllFiles" + e.getMessage());
  1090. }
  1091. }
  1092. }
  1093. private void resetShareFlagsInFolder(OCFile folder) {
  1094. ContentValues cv = new ContentValues();
  1095. cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, false);
  1096. cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false);
  1097. cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
  1098. String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  1099. ProviderTableMeta.FILE_PARENT + "=?";
  1100. String [] whereArgs = new String[] { mAccount.name , String.valueOf(folder.getFileId()) };
  1101. if (getContentResolver() != null) {
  1102. getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
  1103. } else {
  1104. try {
  1105. getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where,
  1106. whereArgs);
  1107. } catch (RemoteException e) {
  1108. Log_OC.e(TAG, "Exception in resetShareFlagsInFolder " + e.getMessage());
  1109. }
  1110. }
  1111. }
  1112. private void resetShareFlagInAFile(String filePath){
  1113. ContentValues cv = new ContentValues();
  1114. cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, false);
  1115. cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false);
  1116. cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
  1117. String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  1118. ProviderTableMeta.FILE_PATH+ "=?";
  1119. String [] whereArgs = new String[] { mAccount.name , filePath };
  1120. if (getContentResolver() != null) {
  1121. getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
  1122. } else {
  1123. try {
  1124. getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where,
  1125. whereArgs);
  1126. } catch (RemoteException e) {
  1127. Log_OC.e(TAG, "Exception in resetShareFlagsInFolder " + e.getMessage());
  1128. }
  1129. }
  1130. }
  1131. private void cleanShares() {
  1132. String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
  1133. String[] whereArgs = new String[]{mAccount.name};
  1134. if (getContentResolver() != null) {
  1135. getContentResolver().delete(ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs);
  1136. } else {
  1137. try {
  1138. getContentProviderClient().delete(ProviderTableMeta.CONTENT_URI_SHARE, where,
  1139. whereArgs);
  1140. } catch (RemoteException e) {
  1141. Log_OC.e(TAG, "Exception in cleanShares" + e.getMessage());
  1142. }
  1143. }
  1144. }
  1145. public void saveShares(Collection<OCShare> shares) {
  1146. cleanShares();
  1147. if (shares != null) {
  1148. ArrayList<ContentProviderOperation> operations =
  1149. new ArrayList<ContentProviderOperation>(shares.size());
  1150. // prepare operations to insert or update files to save in the given folder
  1151. for (OCShare share : shares) {
  1152. ContentValues cv = new ContentValues();
  1153. cv.put(ProviderTableMeta.OCSHARES_FILE_SOURCE, share.getFileSource());
  1154. cv.put(ProviderTableMeta.OCSHARES_ITEM_SOURCE, share.getItemSource());
  1155. cv.put(ProviderTableMeta.OCSHARES_SHARE_TYPE, share.getShareType().getValue());
  1156. cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH, share.getShareWith());
  1157. cv.put(ProviderTableMeta.OCSHARES_PATH, share.getPath());
  1158. cv.put(ProviderTableMeta.OCSHARES_PERMISSIONS, share.getPermissions());
  1159. cv.put(ProviderTableMeta.OCSHARES_SHARED_DATE, share.getSharedDate());
  1160. cv.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE, share.getExpirationDate());
  1161. cv.put(ProviderTableMeta.OCSHARES_TOKEN, share.getToken());
  1162. cv.put(
  1163. ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME,
  1164. share.getSharedWithDisplayName()
  1165. );
  1166. cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
  1167. cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
  1168. cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
  1169. cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
  1170. if (shareExistsForRemoteId(share.getRemoteId())) {
  1171. // updating an existing file
  1172. operations.add(
  1173. ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
  1174. withValues(cv).
  1175. withSelection(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
  1176. new String[]{String.valueOf(share.getRemoteId())})
  1177. .build());
  1178. } else {
  1179. // adding a new file
  1180. operations.add(
  1181. ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI_SHARE).
  1182. withValues(cv).
  1183. build()
  1184. );
  1185. }
  1186. }
  1187. // apply operations in batch
  1188. if (operations.size() > 0) {
  1189. @SuppressWarnings("unused")
  1190. ContentProviderResult[] results = null;
  1191. Log_OC.d(TAG, "Sending " + operations.size() +
  1192. " operations to FileContentProvider");
  1193. try {
  1194. if (getContentResolver() != null) {
  1195. results = getContentResolver().applyBatch(MainApp.getAuthority(),
  1196. operations);
  1197. } else {
  1198. results = getContentProviderClient().applyBatch(operations);
  1199. }
  1200. } catch (OperationApplicationException e) {
  1201. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1202. } catch (RemoteException e) {
  1203. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1204. }
  1205. }
  1206. }
  1207. }
  1208. public void updateSharedFiles(Collection<OCFile> sharedFiles) {
  1209. resetShareFlagsInAllFiles();
  1210. if (sharedFiles != null) {
  1211. ArrayList<ContentProviderOperation> operations =
  1212. new ArrayList<ContentProviderOperation>(sharedFiles.size());
  1213. // prepare operations to insert or update files to save in the given folder
  1214. for (OCFile file : sharedFiles) {
  1215. ContentValues cv = new ContentValues();
  1216. cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
  1217. cv.put(
  1218. ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
  1219. file.getModificationTimestampAtLastSyncForData()
  1220. );
  1221. cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
  1222. cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
  1223. cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
  1224. cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
  1225. cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
  1226. cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
  1227. if (!file.isFolder()) {
  1228. cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
  1229. }
  1230. cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
  1231. cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
  1232. cv.put(
  1233. ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA,
  1234. file.getLastSyncDateForData()
  1235. );
  1236. cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.isFavorite() ? 1 : 0);
  1237. cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
  1238. cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, file.isSharedViaLink() ? 1 : 0);
  1239. cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, file.isSharedWithSharee() ? 1 : 0);
  1240. cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
  1241. cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
  1242. cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
  1243. cv.put(
  1244. ProviderTableMeta.FILE_UPDATE_THUMBNAIL,
  1245. file.needsUpdateThumbnail() ? 1 : 0
  1246. );
  1247. cv.put(
  1248. ProviderTableMeta.FILE_IS_DOWNLOADING,
  1249. file.isDownloading() ? 1 : 0
  1250. );
  1251. cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, file.getEtagInConflict());
  1252. boolean existsByPath = fileExists(file.getRemotePath());
  1253. if (existsByPath || fileExists(file.getFileId())) {
  1254. // updating an existing file
  1255. operations.add(
  1256. ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
  1257. withValues(cv).
  1258. withSelection(ProviderTableMeta._ID + "=?",
  1259. new String[]{String.valueOf(file.getFileId())})
  1260. .build());
  1261. } else {
  1262. // adding a new file
  1263. operations.add(
  1264. ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).
  1265. withValues(cv).
  1266. build()
  1267. );
  1268. }
  1269. }
  1270. // apply operations in batch
  1271. if (operations.size() > 0) {
  1272. @SuppressWarnings("unused")
  1273. ContentProviderResult[] results = null;
  1274. Log_OC.d(TAG, "Sending " + operations.size() +
  1275. " operations to FileContentProvider");
  1276. try {
  1277. if (getContentResolver() != null) {
  1278. results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
  1279. } else {
  1280. results = getContentProviderClient().applyBatch(operations);
  1281. }
  1282. } catch (OperationApplicationException e) {
  1283. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1284. } catch (RemoteException e) {
  1285. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1286. }
  1287. }
  1288. }
  1289. }
  1290. public void removeShare(OCShare share) {
  1291. Uri share_uri = ProviderTableMeta.CONTENT_URI_SHARE;
  1292. String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" + " AND " +
  1293. ProviderTableMeta._ID + "=?";
  1294. String [] whereArgs = new String[]{mAccount.name, Long.toString(share.getId())};
  1295. if (getContentProviderClient() != null) {
  1296. try {
  1297. getContentProviderClient().delete(share_uri, where, whereArgs);
  1298. } catch (RemoteException e) {
  1299. e.printStackTrace();
  1300. }
  1301. } else {
  1302. getContentResolver().delete(share_uri, where, whereArgs);
  1303. }
  1304. }
  1305. public void saveSharesDB(ArrayList<OCShare> shares) {
  1306. ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
  1307. // Reset flags & Remove shares for this files
  1308. String filePath = "";
  1309. for (OCShare share: shares) {
  1310. if (filePath != share.getPath()){
  1311. filePath = share.getPath();
  1312. resetShareFlagInAFile(filePath);
  1313. operations = prepareRemoveSharesInFile(filePath, operations);
  1314. }
  1315. }
  1316. // Add operations to insert shares
  1317. operations = prepareInsertShares(shares, operations);
  1318. // apply operations in batch
  1319. if (operations.size() > 0) {
  1320. Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
  1321. try {
  1322. if (getContentResolver() != null) {
  1323. getContentResolver().applyBatch(MainApp.getAuthority(), operations);
  1324. } else {
  1325. getContentProviderClient().applyBatch(operations);
  1326. }
  1327. } catch (OperationApplicationException e) {
  1328. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1329. } catch (RemoteException e) {
  1330. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1331. }
  1332. }
  1333. // // TODO: review if it is needed
  1334. // // Update shared files
  1335. // ArrayList<OCFile> sharedFiles = new ArrayList<OCFile>();
  1336. //
  1337. // for (OCShare share : shares) {
  1338. // // Get the path
  1339. // String path = share.getPath();
  1340. // if (share.isFolder()) {
  1341. // path = path + FileUtils.PATH_SEPARATOR;
  1342. // }
  1343. //
  1344. // // Update OCFile with data from share: ShareByLink, publicLink and
  1345. // OCFile file = getFileByPath(path);
  1346. // if (file != null) {
  1347. // if (share.getShareType().equals(ShareType.PUBLIC_LINK)) {
  1348. // file.setShareViaLink(true);
  1349. // sharedFiles.add(file);
  1350. // }
  1351. // }
  1352. // }
  1353. //
  1354. // // TODO: Review
  1355. // updateSharedFiles(sharedFiles);
  1356. }
  1357. public void removeSharesForFile(String remotePath) {
  1358. resetShareFlagInAFile(remotePath);
  1359. ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
  1360. operations = prepareRemoveSharesInFile(remotePath, operations);
  1361. // apply operations in batch
  1362. if (operations.size() > 0) {
  1363. Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
  1364. try {
  1365. if (getContentResolver() != null) {
  1366. getContentResolver().applyBatch(MainApp.getAuthority(), operations);
  1367. } else {
  1368. getContentProviderClient().applyBatch(operations);
  1369. }
  1370. } catch (OperationApplicationException e) {
  1371. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1372. } catch (RemoteException e) {
  1373. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1374. }
  1375. }
  1376. }
  1377. public void saveSharesInFolder(ArrayList<OCShare> shares, OCFile folder) {
  1378. resetShareFlagsInFolder(folder);
  1379. ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
  1380. operations = prepareRemoveSharesInFolder(folder, operations);
  1381. if (shares != null) {
  1382. // prepare operations to insert or update files to save in the given folder
  1383. operations = prepareInsertShares(shares, operations);
  1384. }
  1385. // apply operations in batch
  1386. if (operations.size() > 0) {
  1387. Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
  1388. try {
  1389. if (getContentResolver() != null) {
  1390. getContentResolver().applyBatch(MainApp.getAuthority(), operations);
  1391. } else {
  1392. getContentProviderClient().applyBatch(operations);
  1393. }
  1394. } catch (OperationApplicationException e) {
  1395. Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
  1396. } catch (RemoteException e) {
  1397. }
  1398. }
  1399. }
  1400. /**
  1401. * Prepare operations to insert or update files to save in the given folder
  1402. * @param shares List of shares to insert
  1403. * @param operations List of operations
  1404. * @return
  1405. */
  1406. private ArrayList<ContentProviderOperation> prepareInsertShares(
  1407. ArrayList<OCShare> shares, ArrayList<ContentProviderOperation> operations) {
  1408. if (shares != null) {
  1409. // prepare operations to insert or update files to save in the given folder
  1410. for (OCShare share : shares) {
  1411. ContentValues cv = new ContentValues();
  1412. cv.put(ProviderTableMeta.OCSHARES_FILE_SOURCE, share.getFileSource());
  1413. cv.put(ProviderTableMeta.OCSHARES_ITEM_SOURCE, share.getItemSource());
  1414. cv.put(ProviderTableMeta.OCSHARES_SHARE_TYPE, share.getShareType().getValue());
  1415. cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH, share.getShareWith());
  1416. cv.put(ProviderTableMeta.OCSHARES_PATH, share.getPath());
  1417. cv.put(ProviderTableMeta.OCSHARES_PERMISSIONS, share.getPermissions());
  1418. cv.put(ProviderTableMeta.OCSHARES_SHARED_DATE, share.getSharedDate());
  1419. cv.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE, share.getExpirationDate());
  1420. cv.put(ProviderTableMeta.OCSHARES_TOKEN, share.getToken());
  1421. cv.put(
  1422. ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME,
  1423. share.getSharedWithDisplayName()
  1424. );
  1425. cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
  1426. cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
  1427. cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
  1428. cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
  1429. // adding a new share resource
  1430. operations.add(
  1431. ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI_SHARE).
  1432. withValues(cv).
  1433. build()
  1434. );
  1435. }
  1436. }
  1437. return operations;
  1438. }
  1439. private ArrayList<ContentProviderOperation> prepareRemoveSharesInFolder(
  1440. OCFile folder, ArrayList<ContentProviderOperation> preparedOperations) {
  1441. if (folder != null) {
  1442. String where = ProviderTableMeta.OCSHARES_PATH + "=?" + " AND "
  1443. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
  1444. String [] whereArgs = new String[]{ "", mAccount.name };
  1445. Vector<OCFile> files = getFolderContent(folder, false);
  1446. for (OCFile file : files) {
  1447. whereArgs[0] = file.getRemotePath();
  1448. preparedOperations.add(
  1449. ContentProviderOperation.newDelete(ProviderTableMeta.CONTENT_URI_SHARE).
  1450. withSelection(where, whereArgs).
  1451. build()
  1452. );
  1453. }
  1454. }
  1455. return preparedOperations;
  1456. }
  1457. private ArrayList<ContentProviderOperation> prepareRemoveSharesInFile(
  1458. String filePath, ArrayList<ContentProviderOperation> preparedOperations) {
  1459. String where = ProviderTableMeta.OCSHARES_PATH + "=?" + " AND "
  1460. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
  1461. String[] whereArgs = new String[]{filePath, mAccount.name};
  1462. preparedOperations.add(
  1463. ContentProviderOperation.newDelete(ProviderTableMeta.CONTENT_URI_SHARE).
  1464. withSelection(where, whereArgs).
  1465. build()
  1466. );
  1467. return preparedOperations;
  1468. }
  1469. public ArrayList<OCShare> getSharesWithForAFile(String filePath, String accountName){
  1470. // Condition
  1471. String where = ProviderTableMeta.OCSHARES_PATH + "=?" + " AND "
  1472. + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?"+ "AND"
  1473. + " (" + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR "
  1474. + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR "
  1475. + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? ) ";
  1476. String [] whereArgs = new String[]{ filePath, accountName ,
  1477. Integer.toString(ShareType.USER.getValue()),
  1478. Integer.toString(ShareType.GROUP.getValue()),
  1479. Integer.toString(ShareType.FEDERATED.getValue())};
  1480. Cursor c = null;
  1481. if (getContentResolver() != null) {
  1482. c = getContentResolver().query(
  1483. ProviderTableMeta.CONTENT_URI_SHARE,
  1484. null, where, whereArgs, null);
  1485. } else {
  1486. try {
  1487. c = getContentProviderClient().query(
  1488. ProviderTableMeta.CONTENT_URI_SHARE,
  1489. null, where, whereArgs, null);
  1490. } catch (RemoteException e) {
  1491. Log_OC.e(TAG, "Could not get list of shares with: " + e.getMessage());
  1492. c = null;
  1493. }
  1494. }
  1495. ArrayList<OCShare> shares = new ArrayList<OCShare>();
  1496. OCShare share = null;
  1497. if (c.moveToFirst()) {
  1498. do {
  1499. share = createShareInstance(c);
  1500. shares.add(share);
  1501. // }
  1502. } while (c.moveToNext());
  1503. }
  1504. c.close();
  1505. return shares;
  1506. }
  1507. public static void triggerMediaScan(String path) {
  1508. if (path != null) {
  1509. Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
  1510. intent.setData(Uri.fromFile(new File(path)));
  1511. MainApp.getAppContext().sendBroadcast(intent);
  1512. }
  1513. }
  1514. public void deleteFileInMediaScan(String path) {
  1515. String mimetypeString = FileStorageUtils.getMimeTypeFromName(path);
  1516. ContentResolver contentResolver = getContentResolver();
  1517. if (contentResolver != null) {
  1518. if (MimeTypeUtil.isImage(mimetypeString)) {
  1519. // Images
  1520. contentResolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
  1521. MediaStore.Images.Media.DATA + "=?", new String[]{path});
  1522. } else if (MimeTypeUtil.isAudio(mimetypeString)) {
  1523. // Audio
  1524. contentResolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
  1525. MediaStore.Audio.Media.DATA + "=?", new String[]{path});
  1526. } else if (MimeTypeUtil.isVideo(mimetypeString)) {
  1527. // Video
  1528. contentResolver.delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
  1529. MediaStore.Video.Media.DATA + "=?", new String[]{path});
  1530. }
  1531. } else {
  1532. ContentProviderClient contentProviderClient = getContentProviderClient();
  1533. try {
  1534. if (MimeTypeUtil.isImage(mimetypeString)) {
  1535. // Images
  1536. contentProviderClient.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
  1537. MediaStore.Images.Media.DATA + "=?", new String[]{path});
  1538. } else if (MimeTypeUtil.isAudio(mimetypeString)) {
  1539. // Audio
  1540. contentProviderClient.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
  1541. MediaStore.Audio.Media.DATA + "=?", new String[]{path});
  1542. } else if (MimeTypeUtil.isVideo(mimetypeString)) {
  1543. // Video
  1544. contentProviderClient.delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
  1545. MediaStore.Video.Media.DATA + "=?", new String[]{path});
  1546. }
  1547. } catch (RemoteException e) {
  1548. Log_OC.e(TAG, "Exception deleting media file in MediaStore " + e.getMessage());
  1549. }
  1550. }
  1551. }
  1552. public void saveConflict(OCFile file, String etagInConflict) {
  1553. if (!file.isDown()) {
  1554. etagInConflict = null;
  1555. }
  1556. ContentValues cv = new ContentValues();
  1557. cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, etagInConflict);
  1558. int updated = 0;
  1559. if (getContentResolver() != null) {
  1560. updated = getContentResolver().update(
  1561. ProviderTableMeta.CONTENT_URI_FILE,
  1562. cv,
  1563. ProviderTableMeta._ID + "=?",
  1564. new String[] { String.valueOf(file.getFileId())}
  1565. );
  1566. } else {
  1567. try {
  1568. updated = getContentProviderClient().update(
  1569. ProviderTableMeta.CONTENT_URI_FILE,
  1570. cv,
  1571. ProviderTableMeta._ID + "=?",
  1572. new String[]{String.valueOf(file.getFileId())}
  1573. );
  1574. } catch (RemoteException e) {
  1575. Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
  1576. }
  1577. }
  1578. Log_OC.d(TAG, "Number of files updated with CONFLICT: " + updated);
  1579. if (updated > 0) {
  1580. if (etagInConflict != null) {
  1581. /// set conflict in all ancestor folders
  1582. long parentId = file.getParentId();
  1583. Set<String> ancestorIds = new HashSet<String>();
  1584. while (parentId != FileDataStorageManager.ROOT_PARENT_ID) {
  1585. ancestorIds.add(Long.toString(parentId));
  1586. parentId = getFileById(parentId).getParentId();
  1587. }
  1588. if (ancestorIds.size() > 0) {
  1589. StringBuffer whereBuffer = new StringBuffer();
  1590. whereBuffer.append(ProviderTableMeta._ID).append(" IN (");
  1591. for (int i = 0; i < ancestorIds.size() - 1; i++) {
  1592. whereBuffer.append("?,");
  1593. }
  1594. whereBuffer.append("?");
  1595. whereBuffer.append(")");
  1596. if (getContentResolver() != null) {
  1597. updated = getContentResolver().update(
  1598. ProviderTableMeta.CONTENT_URI_FILE,
  1599. cv,
  1600. whereBuffer.toString(),
  1601. ancestorIds.toArray(new String[]{})
  1602. );
  1603. } else {
  1604. try {
  1605. updated = getContentProviderClient().update(
  1606. ProviderTableMeta.CONTENT_URI_FILE,
  1607. cv,
  1608. whereBuffer.toString(),
  1609. ancestorIds.toArray(new String[]{})
  1610. );
  1611. } catch (RemoteException e) {
  1612. Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
  1613. }
  1614. }
  1615. } // else file is ROOT folder, no parent to set in conflict
  1616. } else {
  1617. /// update conflict in ancestor folders
  1618. // (not directly unset; maybe there are more conflicts below them)
  1619. String parentPath = file.getRemotePath();
  1620. if (parentPath.endsWith(OCFile.PATH_SEPARATOR)) {
  1621. parentPath = parentPath.substring(0, parentPath.length() - 1);
  1622. }
  1623. parentPath = parentPath.substring(0, parentPath.lastIndexOf(OCFile.PATH_SEPARATOR) + 1);
  1624. Log_OC.d(TAG, "checking parents to remove conflict; STARTING with " + parentPath);
  1625. while (parentPath.length() > 0) {
  1626. String whereForDescencentsInConflict =
  1627. ProviderTableMeta.FILE_ETAG_IN_CONFLICT + " IS NOT NULL AND " +
  1628. ProviderTableMeta.FILE_CONTENT_TYPE + " != 'DIR' AND " +
  1629. ProviderTableMeta.FILE_ACCOUNT_OWNER + " = ? AND " +
  1630. ProviderTableMeta.FILE_PATH + " LIKE ?";
  1631. Cursor descendentsInConflict = null;
  1632. if (getContentResolver() != null) {
  1633. descendentsInConflict = getContentResolver().query(
  1634. ProviderTableMeta.CONTENT_URI_FILE,
  1635. new String[]{ProviderTableMeta._ID},
  1636. whereForDescencentsInConflict,
  1637. new String[]{mAccount.name, parentPath + "%"},
  1638. null
  1639. );
  1640. } else {
  1641. try {
  1642. descendentsInConflict = getContentProviderClient().query(
  1643. ProviderTableMeta.CONTENT_URI_FILE,
  1644. new String[]{ProviderTableMeta._ID},
  1645. whereForDescencentsInConflict,
  1646. new String[]{mAccount.name, parentPath + "%"},
  1647. null
  1648. );
  1649. } catch (RemoteException e) {
  1650. Log_OC.e(TAG, "Failed querying for descendents in conflict " + e.getMessage());
  1651. }
  1652. }
  1653. if (descendentsInConflict == null || descendentsInConflict.getCount() == 0) {
  1654. Log_OC.d(TAG, "NO MORE conflicts in " + parentPath);
  1655. if (getContentResolver() != null) {
  1656. updated = getContentResolver().update(
  1657. ProviderTableMeta.CONTENT_URI_FILE,
  1658. cv,
  1659. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  1660. ProviderTableMeta.FILE_PATH + "=?",
  1661. new String[]{mAccount.name, parentPath}
  1662. );
  1663. } else {
  1664. try {
  1665. updated = getContentProviderClient().update(
  1666. ProviderTableMeta.CONTENT_URI_FILE,
  1667. cv,
  1668. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  1669. ProviderTableMeta.FILE_PATH + "=?"
  1670. , new String[]{mAccount.name, parentPath}
  1671. );
  1672. } catch (RemoteException e) {
  1673. Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
  1674. }
  1675. }
  1676. } else {
  1677. Log_OC.d(TAG, "STILL " + descendentsInConflict.getCount() + " in " + parentPath);
  1678. }
  1679. if (descendentsInConflict != null) {
  1680. descendentsInConflict.close();
  1681. }
  1682. parentPath = parentPath.substring(0, parentPath.length() - 1); // trim last /
  1683. parentPath = parentPath.substring(0, parentPath.lastIndexOf(OCFile.PATH_SEPARATOR) + 1);
  1684. Log_OC.d(TAG, "checking parents to remove conflict; NEXT " + parentPath);
  1685. }
  1686. }
  1687. }
  1688. }
  1689. public OCCapability saveCapabilities(OCCapability capability){
  1690. // Prepare capabilities data
  1691. ContentValues cv = new ContentValues();
  1692. cv.put(ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME, mAccount.name);
  1693. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_MAYOR, capability.getVersionMayor());
  1694. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_MINOR, capability.getVersionMinor());
  1695. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_MICRO, capability.getVersionMicro());
  1696. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_STRING, capability.getVersionString());
  1697. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_EDITION, capability.getVersionEdition());
  1698. cv.put(ProviderTableMeta.CAPABILITIES_CORE_POLLINTERVAL, capability.getCorePollinterval());
  1699. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_API_ENABLED, capability.getFilesSharingApiEnabled().getValue());
  1700. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ENABLED,
  1701. capability.getFilesSharingPublicEnabled().getValue());
  1702. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED,
  1703. capability.getFilesSharingPublicPasswordEnforced().getValue());
  1704. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED,
  1705. capability.getFilesSharingPublicExpireDateEnabled().getValue());
  1706. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS,
  1707. capability.getFilesSharingPublicExpireDateDays());
  1708. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENFORCED,
  1709. capability.getFilesSharingPublicExpireDateEnforced().getValue());
  1710. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_SEND_MAIL,
  1711. capability.getFilesSharingPublicSendMail().getValue());
  1712. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_UPLOAD,
  1713. capability.getFilesSharingPublicUpload().getValue());
  1714. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_USER_SEND_MAIL,
  1715. capability.getFilesSharingUserSendMail().getValue());
  1716. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_RESHARING, capability.getFilesSharingResharing().getValue());
  1717. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_OUTGOING,
  1718. capability.getFilesSharingFederationOutgoing().getValue());
  1719. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_INCOMING,
  1720. capability.getFilesSharingFederationIncoming().getValue());
  1721. cv.put(ProviderTableMeta.CAPABILITIES_FILES_BIGFILECHUNKING, capability.getFilesBigFileChuncking().getValue());
  1722. cv.put(ProviderTableMeta.CAPABILITIES_FILES_UNDELETE, capability.getFilesUndelete().getValue());
  1723. cv.put(ProviderTableMeta.CAPABILITIES_FILES_VERSIONING, capability.getFilesVersioning().getValue());
  1724. cv.put(ProviderTableMeta.CAPABILITIES_FILES_DROP, capability.getFilesFileDrop().getValue());
  1725. if (capabilityExists(mAccount.name)) {
  1726. if (getContentResolver() != null) {
  1727. getContentResolver().update(ProviderTableMeta.CONTENT_URI_CAPABILITIES, cv,
  1728. ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + "=?",
  1729. new String[]{mAccount.name});
  1730. } else {
  1731. try {
  1732. getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_CAPABILITIES,
  1733. cv, ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + "=?",
  1734. new String[]{mAccount.name});
  1735. } catch (RemoteException e) {
  1736. Log_OC.e(TAG,
  1737. "Fail to insert insert file to database "
  1738. + e.getMessage());
  1739. }
  1740. }
  1741. } else {
  1742. Uri result_uri = null;
  1743. if (getContentResolver() != null) {
  1744. result_uri = getContentResolver().insert(
  1745. ProviderTableMeta.CONTENT_URI_CAPABILITIES, cv);
  1746. } else {
  1747. try {
  1748. result_uri = getContentProviderClient().insert(
  1749. ProviderTableMeta.CONTENT_URI_CAPABILITIES, cv);
  1750. } catch (RemoteException e) {
  1751. Log_OC.e(TAG,
  1752. "Fail to insert insert capability to database "
  1753. + e.getMessage());
  1754. }
  1755. }
  1756. if (result_uri != null) {
  1757. long new_id = Long.parseLong(result_uri.getPathSegments()
  1758. .get(1));
  1759. capability.setId(new_id);
  1760. capability.setAccountName(mAccount.name);
  1761. }
  1762. }
  1763. return capability;
  1764. }
  1765. private boolean capabilityExists(String accountName) {
  1766. Cursor c = getCapabilityCursorForAccount(accountName);
  1767. boolean exists = false;
  1768. if (c != null) {
  1769. exists = c.moveToFirst();
  1770. c.close();
  1771. }
  1772. return exists;
  1773. }
  1774. private Cursor getCapabilityCursorForAccount(String accountName){
  1775. Cursor c = null;
  1776. if (getContentResolver() != null) {
  1777. c = getContentResolver()
  1778. .query(ProviderTableMeta.CONTENT_URI_CAPABILITIES,
  1779. null,
  1780. ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + "=? ",
  1781. new String[]{accountName}, null);
  1782. } else {
  1783. try {
  1784. c = getContentProviderClient().query(
  1785. ProviderTableMeta.CONTENT_URI_CAPABILITIES,
  1786. null,
  1787. ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + "=? ",
  1788. new String[]{accountName}, null);
  1789. } catch (RemoteException e) {
  1790. Log_OC.e(TAG,
  1791. "Couldn't determine capability existance, assuming non existance: "
  1792. + e.getMessage());
  1793. }
  1794. }
  1795. return c;
  1796. }
  1797. public OCCapability getCapability(String accountName){
  1798. OCCapability capability = null;
  1799. Cursor c = getCapabilityCursorForAccount(accountName);
  1800. if (c.moveToFirst()) {
  1801. capability = createCapabilityInstance(c);
  1802. } else {
  1803. capability = new OCCapability(); // return default with all UNKNOWN
  1804. }
  1805. c.close();
  1806. return capability;
  1807. }
  1808. private OCCapability createCapabilityInstance(Cursor c) {
  1809. OCCapability capability = null;
  1810. if (c != null) {
  1811. capability = new OCCapability();
  1812. capability.setId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
  1813. capability.setAccountName(c.getString(c
  1814. .getColumnIndex(ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME)));
  1815. capability.setVersionMayor(c.getInt(c
  1816. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_MAYOR)));
  1817. capability.setVersionMinor(c.getInt(c
  1818. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_MINOR)));
  1819. capability.setVersionMicro(c.getInt(c
  1820. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_MICRO)));
  1821. capability.setVersionString(c.getString(c
  1822. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_STRING)));
  1823. capability.setVersionEdition(c.getString(c
  1824. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_EDITION)));
  1825. capability.setCorePollinterval(c.getInt(c
  1826. .getColumnIndex(ProviderTableMeta.CAPABILITIES_CORE_POLLINTERVAL)));
  1827. capability.setFilesSharingApiEnabled(CapabilityBooleanType.fromValue(c.getInt(c
  1828. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_API_ENABLED))));
  1829. capability.setFilesSharingPublicEnabled(CapabilityBooleanType.fromValue(c.getInt(c
  1830. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ENABLED))));
  1831. capability.setFilesSharingPublicPasswordEnforced(CapabilityBooleanType.fromValue(c.getInt(c
  1832. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED))));
  1833. capability.setFilesSharingPublicExpireDateEnabled(CapabilityBooleanType.fromValue(c.getInt(c
  1834. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED))));
  1835. capability.setFilesSharingPublicExpireDateDays(c.getInt(c
  1836. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS)));
  1837. capability.setFilesSharingPublicExpireDateEnforced(CapabilityBooleanType.fromValue(c.getInt(c
  1838. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENFORCED))));
  1839. capability.setFilesSharingPublicSendMail(CapabilityBooleanType.fromValue(c.getInt(c
  1840. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_SEND_MAIL))));
  1841. capability.setFilesSharingPublicUpload(CapabilityBooleanType.fromValue(c.getInt(c
  1842. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_UPLOAD))));
  1843. capability.setFilesSharingUserSendMail(CapabilityBooleanType.fromValue(c.getInt(c
  1844. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_USER_SEND_MAIL))));
  1845. capability.setFilesSharingResharing(CapabilityBooleanType.fromValue(c.getInt(c
  1846. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_RESHARING))));
  1847. capability.setFilesSharingFederationOutgoing(CapabilityBooleanType.fromValue(c.getInt(c
  1848. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_OUTGOING))));
  1849. capability.setFilesSharingFederationIncoming(CapabilityBooleanType.fromValue(c.getInt(c
  1850. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_INCOMING))));
  1851. capability.setFilesBigFileChuncking(CapabilityBooleanType.fromValue(c.getInt(c
  1852. .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_BIGFILECHUNKING))));
  1853. capability.setFilesUndelete(CapabilityBooleanType.fromValue(c.getInt(c
  1854. .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_UNDELETE))));
  1855. capability.setFilesVersioning(CapabilityBooleanType.fromValue(c.getInt(c
  1856. .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_VERSIONING))));
  1857. capability.setFilesFileDrop(CapabilityBooleanType.fromValue(c.getInt(c
  1858. .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_DROP))));
  1859. }
  1860. return capability;
  1861. }
  1862. }