FileDataStorageManager.java 92 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081
  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 cursor = 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. cursor = getContentResolver().query(
  1022. ProviderTableMeta.CONTENT_URI_SHARE,
  1023. null,
  1024. selection, selectionArgs,
  1025. null);
  1026. } else {
  1027. try {
  1028. cursor = 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. cursor = null;
  1036. }
  1037. }
  1038. OCShare share = null;
  1039. if (cursor != null && cursor.moveToFirst()) {
  1040. share = createShareInstance(cursor);
  1041. cursor.close();
  1042. }
  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 cursor = null;
  1481. if (getContentResolver() != null) {
  1482. cursor = getContentResolver().query(
  1483. ProviderTableMeta.CONTENT_URI_SHARE,
  1484. null, where, whereArgs, null);
  1485. } else {
  1486. try {
  1487. cursor = 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. cursor = null;
  1493. }
  1494. }
  1495. ArrayList<OCShare> shares = new ArrayList<OCShare>();
  1496. OCShare share = null;
  1497. if (cursor != null && cursor.moveToFirst()) {
  1498. do {
  1499. share = createShareInstance(cursor);
  1500. shares.add(share);
  1501. } while (cursor.moveToNext());
  1502. cursor.close();
  1503. }
  1504. return shares;
  1505. }
  1506. public static void triggerMediaScan(String path) {
  1507. if (path != null) {
  1508. Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
  1509. intent.setData(Uri.fromFile(new File(path)));
  1510. MainApp.getAppContext().sendBroadcast(intent);
  1511. }
  1512. }
  1513. public void deleteFileInMediaScan(String path) {
  1514. String mimetypeString = FileStorageUtils.getMimeTypeFromName(path);
  1515. ContentResolver contentResolver = getContentResolver();
  1516. if (contentResolver != null) {
  1517. if (MimeTypeUtil.isImage(mimetypeString)) {
  1518. // Images
  1519. contentResolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
  1520. MediaStore.Images.Media.DATA + "=?", new String[]{path});
  1521. } else if (MimeTypeUtil.isAudio(mimetypeString)) {
  1522. // Audio
  1523. contentResolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
  1524. MediaStore.Audio.Media.DATA + "=?", new String[]{path});
  1525. } else if (MimeTypeUtil.isVideo(mimetypeString)) {
  1526. // Video
  1527. contentResolver.delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
  1528. MediaStore.Video.Media.DATA + "=?", new String[]{path});
  1529. }
  1530. } else {
  1531. ContentProviderClient contentProviderClient = getContentProviderClient();
  1532. try {
  1533. if (MimeTypeUtil.isImage(mimetypeString)) {
  1534. // Images
  1535. contentProviderClient.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
  1536. MediaStore.Images.Media.DATA + "=?", new String[]{path});
  1537. } else if (MimeTypeUtil.isAudio(mimetypeString)) {
  1538. // Audio
  1539. contentProviderClient.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
  1540. MediaStore.Audio.Media.DATA + "=?", new String[]{path});
  1541. } else if (MimeTypeUtil.isVideo(mimetypeString)) {
  1542. // Video
  1543. contentProviderClient.delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
  1544. MediaStore.Video.Media.DATA + "=?", new String[]{path});
  1545. }
  1546. } catch (RemoteException e) {
  1547. Log_OC.e(TAG, "Exception deleting media file in MediaStore " + e.getMessage());
  1548. }
  1549. }
  1550. }
  1551. public void saveConflict(OCFile file, String etagInConflict) {
  1552. if (!file.isDown()) {
  1553. etagInConflict = null;
  1554. }
  1555. ContentValues cv = new ContentValues();
  1556. cv.put(ProviderTableMeta.FILE_ETAG_IN_CONFLICT, etagInConflict);
  1557. int updated = 0;
  1558. if (getContentResolver() != null) {
  1559. updated = getContentResolver().update(
  1560. ProviderTableMeta.CONTENT_URI_FILE,
  1561. cv,
  1562. ProviderTableMeta._ID + "=?",
  1563. new String[] { String.valueOf(file.getFileId())}
  1564. );
  1565. } else {
  1566. try {
  1567. updated = getContentProviderClient().update(
  1568. ProviderTableMeta.CONTENT_URI_FILE,
  1569. cv,
  1570. ProviderTableMeta._ID + "=?",
  1571. new String[]{String.valueOf(file.getFileId())}
  1572. );
  1573. } catch (RemoteException e) {
  1574. Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
  1575. }
  1576. }
  1577. Log_OC.d(TAG, "Number of files updated with CONFLICT: " + updated);
  1578. if (updated > 0) {
  1579. if (etagInConflict != null) {
  1580. /// set conflict in all ancestor folders
  1581. long parentId = file.getParentId();
  1582. Set<String> ancestorIds = new HashSet<String>();
  1583. while (parentId != FileDataStorageManager.ROOT_PARENT_ID) {
  1584. ancestorIds.add(Long.toString(parentId));
  1585. parentId = getFileById(parentId).getParentId();
  1586. }
  1587. if (ancestorIds.size() > 0) {
  1588. StringBuffer whereBuffer = new StringBuffer();
  1589. whereBuffer.append(ProviderTableMeta._ID).append(" IN (");
  1590. for (int i = 0; i < ancestorIds.size() - 1; i++) {
  1591. whereBuffer.append("?,");
  1592. }
  1593. whereBuffer.append("?");
  1594. whereBuffer.append(")");
  1595. if (getContentResolver() != null) {
  1596. updated = getContentResolver().update(
  1597. ProviderTableMeta.CONTENT_URI_FILE,
  1598. cv,
  1599. whereBuffer.toString(),
  1600. ancestorIds.toArray(new String[]{})
  1601. );
  1602. } else {
  1603. try {
  1604. updated = getContentProviderClient().update(
  1605. ProviderTableMeta.CONTENT_URI_FILE,
  1606. cv,
  1607. whereBuffer.toString(),
  1608. ancestorIds.toArray(new String[]{})
  1609. );
  1610. } catch (RemoteException e) {
  1611. Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
  1612. }
  1613. }
  1614. } // else file is ROOT folder, no parent to set in conflict
  1615. } else {
  1616. /// update conflict in ancestor folders
  1617. // (not directly unset; maybe there are more conflicts below them)
  1618. String parentPath = file.getRemotePath();
  1619. if (parentPath.endsWith(OCFile.PATH_SEPARATOR)) {
  1620. parentPath = parentPath.substring(0, parentPath.length() - 1);
  1621. }
  1622. parentPath = parentPath.substring(0, parentPath.lastIndexOf(OCFile.PATH_SEPARATOR) + 1);
  1623. Log_OC.d(TAG, "checking parents to remove conflict; STARTING with " + parentPath);
  1624. while (parentPath.length() > 0) {
  1625. String whereForDescencentsInConflict =
  1626. ProviderTableMeta.FILE_ETAG_IN_CONFLICT + " IS NOT NULL AND " +
  1627. ProviderTableMeta.FILE_CONTENT_TYPE + " != 'DIR' AND " +
  1628. ProviderTableMeta.FILE_ACCOUNT_OWNER + " = ? AND " +
  1629. ProviderTableMeta.FILE_PATH + " LIKE ?";
  1630. Cursor descendentsInConflict = null;
  1631. if (getContentResolver() != null) {
  1632. descendentsInConflict = getContentResolver().query(
  1633. ProviderTableMeta.CONTENT_URI_FILE,
  1634. new String[]{ProviderTableMeta._ID},
  1635. whereForDescencentsInConflict,
  1636. new String[]{mAccount.name, parentPath + "%"},
  1637. null
  1638. );
  1639. } else {
  1640. try {
  1641. descendentsInConflict = getContentProviderClient().query(
  1642. ProviderTableMeta.CONTENT_URI_FILE,
  1643. new String[]{ProviderTableMeta._ID},
  1644. whereForDescencentsInConflict,
  1645. new String[]{mAccount.name, parentPath + "%"},
  1646. null
  1647. );
  1648. } catch (RemoteException e) {
  1649. Log_OC.e(TAG, "Failed querying for descendents in conflict " + e.getMessage());
  1650. }
  1651. }
  1652. if (descendentsInConflict == null || descendentsInConflict.getCount() == 0) {
  1653. Log_OC.d(TAG, "NO MORE conflicts in " + parentPath);
  1654. if (getContentResolver() != null) {
  1655. updated = getContentResolver().update(
  1656. ProviderTableMeta.CONTENT_URI_FILE,
  1657. cv,
  1658. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  1659. ProviderTableMeta.FILE_PATH + "=?",
  1660. new String[]{mAccount.name, parentPath}
  1661. );
  1662. } else {
  1663. try {
  1664. updated = getContentProviderClient().update(
  1665. ProviderTableMeta.CONTENT_URI_FILE,
  1666. cv,
  1667. ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
  1668. ProviderTableMeta.FILE_PATH + "=?"
  1669. , new String[]{mAccount.name, parentPath}
  1670. );
  1671. } catch (RemoteException e) {
  1672. Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
  1673. }
  1674. }
  1675. } else {
  1676. Log_OC.d(TAG, "STILL " + descendentsInConflict.getCount() + " in " + parentPath);
  1677. }
  1678. if (descendentsInConflict != null) {
  1679. descendentsInConflict.close();
  1680. }
  1681. parentPath = parentPath.substring(0, parentPath.length() - 1); // trim last /
  1682. parentPath = parentPath.substring(0, parentPath.lastIndexOf(OCFile.PATH_SEPARATOR) + 1);
  1683. Log_OC.d(TAG, "checking parents to remove conflict; NEXT " + parentPath);
  1684. }
  1685. }
  1686. }
  1687. }
  1688. public OCCapability saveCapabilities(OCCapability capability){
  1689. // Prepare capabilities data
  1690. ContentValues cv = new ContentValues();
  1691. cv.put(ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME, mAccount.name);
  1692. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_MAYOR, capability.getVersionMayor());
  1693. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_MINOR, capability.getVersionMinor());
  1694. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_MICRO, capability.getVersionMicro());
  1695. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_STRING, capability.getVersionString());
  1696. cv.put(ProviderTableMeta.CAPABILITIES_VERSION_EDITION, capability.getVersionEdition());
  1697. cv.put(ProviderTableMeta.CAPABILITIES_CORE_POLLINTERVAL, capability.getCorePollinterval());
  1698. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_API_ENABLED, capability.getFilesSharingApiEnabled().getValue());
  1699. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ENABLED,
  1700. capability.getFilesSharingPublicEnabled().getValue());
  1701. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED,
  1702. capability.getFilesSharingPublicPasswordEnforced().getValue());
  1703. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED,
  1704. capability.getFilesSharingPublicExpireDateEnabled().getValue());
  1705. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS,
  1706. capability.getFilesSharingPublicExpireDateDays());
  1707. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENFORCED,
  1708. capability.getFilesSharingPublicExpireDateEnforced().getValue());
  1709. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_SEND_MAIL,
  1710. capability.getFilesSharingPublicSendMail().getValue());
  1711. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_UPLOAD,
  1712. capability.getFilesSharingPublicUpload().getValue());
  1713. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_USER_SEND_MAIL,
  1714. capability.getFilesSharingUserSendMail().getValue());
  1715. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_RESHARING, capability.getFilesSharingResharing().getValue());
  1716. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_OUTGOING,
  1717. capability.getFilesSharingFederationOutgoing().getValue());
  1718. cv.put(ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_INCOMING,
  1719. capability.getFilesSharingFederationIncoming().getValue());
  1720. cv.put(ProviderTableMeta.CAPABILITIES_FILES_BIGFILECHUNKING, capability.getFilesBigFileChuncking().getValue());
  1721. cv.put(ProviderTableMeta.CAPABILITIES_FILES_UNDELETE, capability.getFilesUndelete().getValue());
  1722. cv.put(ProviderTableMeta.CAPABILITIES_FILES_VERSIONING, capability.getFilesVersioning().getValue());
  1723. cv.put(ProviderTableMeta.CAPABILITIES_FILES_DROP, capability.getFilesFileDrop().getValue());
  1724. if (capabilityExists(mAccount.name)) {
  1725. if (getContentResolver() != null) {
  1726. getContentResolver().update(ProviderTableMeta.CONTENT_URI_CAPABILITIES, cv,
  1727. ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + "=?",
  1728. new String[]{mAccount.name});
  1729. } else {
  1730. try {
  1731. getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_CAPABILITIES,
  1732. cv, ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + "=?",
  1733. new String[]{mAccount.name});
  1734. } catch (RemoteException e) {
  1735. Log_OC.e(TAG,
  1736. "Fail to insert insert file to database "
  1737. + e.getMessage());
  1738. }
  1739. }
  1740. } else {
  1741. Uri result_uri = null;
  1742. if (getContentResolver() != null) {
  1743. result_uri = getContentResolver().insert(
  1744. ProviderTableMeta.CONTENT_URI_CAPABILITIES, cv);
  1745. } else {
  1746. try {
  1747. result_uri = getContentProviderClient().insert(
  1748. ProviderTableMeta.CONTENT_URI_CAPABILITIES, cv);
  1749. } catch (RemoteException e) {
  1750. Log_OC.e(TAG,
  1751. "Fail to insert insert capability to database "
  1752. + e.getMessage());
  1753. }
  1754. }
  1755. if (result_uri != null) {
  1756. long new_id = Long.parseLong(result_uri.getPathSegments()
  1757. .get(1));
  1758. capability.setId(new_id);
  1759. capability.setAccountName(mAccount.name);
  1760. }
  1761. }
  1762. return capability;
  1763. }
  1764. private boolean capabilityExists(String accountName) {
  1765. Cursor c = getCapabilityCursorForAccount(accountName);
  1766. boolean exists = false;
  1767. if (c != null) {
  1768. exists = c.moveToFirst();
  1769. c.close();
  1770. }
  1771. return exists;
  1772. }
  1773. private Cursor getCapabilityCursorForAccount(String accountName){
  1774. Cursor c = null;
  1775. if (getContentResolver() != null) {
  1776. c = getContentResolver()
  1777. .query(ProviderTableMeta.CONTENT_URI_CAPABILITIES,
  1778. null,
  1779. ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + "=? ",
  1780. new String[]{accountName}, null);
  1781. } else {
  1782. try {
  1783. c = getContentProviderClient().query(
  1784. ProviderTableMeta.CONTENT_URI_CAPABILITIES,
  1785. null,
  1786. ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME + "=? ",
  1787. new String[]{accountName}, null);
  1788. } catch (RemoteException e) {
  1789. Log_OC.e(TAG,
  1790. "Couldn't determine capability existance, assuming non existance: "
  1791. + e.getMessage());
  1792. }
  1793. }
  1794. return c;
  1795. }
  1796. public OCCapability getCapability(String accountName){
  1797. OCCapability capability = null;
  1798. Cursor c = getCapabilityCursorForAccount(accountName);
  1799. if (c.moveToFirst()) {
  1800. capability = createCapabilityInstance(c);
  1801. } else {
  1802. capability = new OCCapability(); // return default with all UNKNOWN
  1803. }
  1804. c.close();
  1805. return capability;
  1806. }
  1807. private OCCapability createCapabilityInstance(Cursor c) {
  1808. OCCapability capability = null;
  1809. if (c != null) {
  1810. capability = new OCCapability();
  1811. capability.setId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
  1812. capability.setAccountName(c.getString(c
  1813. .getColumnIndex(ProviderTableMeta.CAPABILITIES_ACCOUNT_NAME)));
  1814. capability.setVersionMayor(c.getInt(c
  1815. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_MAYOR)));
  1816. capability.setVersionMinor(c.getInt(c
  1817. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_MINOR)));
  1818. capability.setVersionMicro(c.getInt(c
  1819. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_MICRO)));
  1820. capability.setVersionString(c.getString(c
  1821. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_STRING)));
  1822. capability.setVersionEdition(c.getString(c
  1823. .getColumnIndex(ProviderTableMeta.CAPABILITIES_VERSION_EDITION)));
  1824. capability.setCorePollinterval(c.getInt(c
  1825. .getColumnIndex(ProviderTableMeta.CAPABILITIES_CORE_POLLINTERVAL)));
  1826. capability.setFilesSharingApiEnabled(CapabilityBooleanType.fromValue(c.getInt(c
  1827. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_API_ENABLED))));
  1828. capability.setFilesSharingPublicEnabled(CapabilityBooleanType.fromValue(c.getInt(c
  1829. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_ENABLED))));
  1830. capability.setFilesSharingPublicPasswordEnforced(CapabilityBooleanType.fromValue(c.getInt(c
  1831. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED))));
  1832. capability.setFilesSharingPublicExpireDateEnabled(CapabilityBooleanType.fromValue(c.getInt(c
  1833. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED))));
  1834. capability.setFilesSharingPublicExpireDateDays(c.getInt(c
  1835. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS)));
  1836. capability.setFilesSharingPublicExpireDateEnforced(CapabilityBooleanType.fromValue(c.getInt(c
  1837. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENFORCED))));
  1838. capability.setFilesSharingPublicSendMail(CapabilityBooleanType.fromValue(c.getInt(c
  1839. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_SEND_MAIL))));
  1840. capability.setFilesSharingPublicUpload(CapabilityBooleanType.fromValue(c.getInt(c
  1841. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_PUBLIC_UPLOAD))));
  1842. capability.setFilesSharingUserSendMail(CapabilityBooleanType.fromValue(c.getInt(c
  1843. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_USER_SEND_MAIL))));
  1844. capability.setFilesSharingResharing(CapabilityBooleanType.fromValue(c.getInt(c
  1845. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_RESHARING))));
  1846. capability.setFilesSharingFederationOutgoing(CapabilityBooleanType.fromValue(c.getInt(c
  1847. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_OUTGOING))));
  1848. capability.setFilesSharingFederationIncoming(CapabilityBooleanType.fromValue(c.getInt(c
  1849. .getColumnIndex(ProviderTableMeta.CAPABILITIES_SHARING_FEDERATION_INCOMING))));
  1850. capability.setFilesBigFileChuncking(CapabilityBooleanType.fromValue(c.getInt(c
  1851. .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_BIGFILECHUNKING))));
  1852. capability.setFilesUndelete(CapabilityBooleanType.fromValue(c.getInt(c
  1853. .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_UNDELETE))));
  1854. capability.setFilesVersioning(CapabilityBooleanType.fromValue(c.getInt(c
  1855. .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_VERSIONING))));
  1856. capability.setFilesFileDrop(CapabilityBooleanType.fromValue(c.getInt(c
  1857. .getColumnIndex(ProviderTableMeta.CAPABILITIES_FILES_DROP))));
  1858. }
  1859. return capability;
  1860. }
  1861. }