5c102d3eaf69e423e363e9beec684a9ec5f282f3
[pub/Android/ownCloud.git] / src / com / owncloud / android / datamodel / FileDataStorageManager.java
1 /* ownCloud Android client application
2 * Copyright (C) 2012 Bartek Przybylski
3 * Copyright (C) 2012-2013 ownCloud Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2,
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 package com.owncloud.android.datamodel;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.Iterator;
26 import java.util.Vector;
27
28 import com.owncloud.android.MainApp;
29 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
30 import com.owncloud.android.utils.FileStorageUtils;
31 import com.owncloud.android.utils.Log_OC;
32
33
34 import android.accounts.Account;
35 import android.content.ContentProviderClient;
36 import android.content.ContentProviderOperation;
37 import android.content.ContentProviderResult;
38 import android.content.ContentResolver;
39 import android.content.ContentUris;
40 import android.content.ContentValues;
41 import android.content.OperationApplicationException;
42 import android.database.Cursor;
43 import android.net.Uri;
44 import android.os.RemoteException;
45
46 public class FileDataStorageManager {
47
48 public static final int ROOT_PARENT_ID = 0;
49
50 private ContentResolver mContentResolver;
51 private ContentProviderClient mContentProviderClient;
52 private Account mAccount;
53
54 private static String TAG = FileDataStorageManager.class.getSimpleName();
55
56
57 public FileDataStorageManager(Account account, ContentResolver cr) {
58 mContentProviderClient = null;
59 mContentResolver = cr;
60 mAccount = account;
61 }
62
63 public FileDataStorageManager(Account account, ContentProviderClient cp) {
64 mContentProviderClient = cp;
65 mContentResolver = null;
66 mAccount = account;
67 }
68
69
70 public void setAccount(Account account) {
71 mAccount = account;
72 }
73
74 public Account getAccount() {
75 return mAccount;
76 }
77
78 public void setContentResolver(ContentResolver cr) {
79 mContentResolver = cr;
80 }
81
82 public ContentResolver getContentResolver() {
83 return mContentResolver;
84 }
85
86 public void setContentProviderClient(ContentProviderClient cp) {
87 mContentProviderClient = cp;
88 }
89
90 public ContentProviderClient getContentProviderClient() {
91 return mContentProviderClient;
92 }
93
94
95 public OCFile getFileByPath(String path) {
96 Cursor c = getCursorForValue(ProviderTableMeta.FILE_PATH, path);
97 OCFile file = null;
98 if (c.moveToFirst()) {
99 file = createFileInstance(c);
100 }
101 c.close();
102 if (file == null && OCFile.ROOT_PATH.equals(path)) {
103 return createRootDir(); // root should always exist
104 }
105 return file;
106 }
107
108
109 public OCFile getFileById(long id) {
110 Cursor c = getCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
111 OCFile file = null;
112 if (c.moveToFirst()) {
113 file = createFileInstance(c);
114 }
115 c.close();
116 return file;
117 }
118
119 public OCFile getFileByLocalPath(String path) {
120 Cursor c = getCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path);
121 OCFile file = null;
122 if (c.moveToFirst()) {
123 file = createFileInstance(c);
124 }
125 c.close();
126 return file;
127 }
128
129 public boolean fileExists(long id) {
130 return fileExists(ProviderTableMeta._ID, String.valueOf(id));
131 }
132
133 public boolean fileExists(String path) {
134 return fileExists(ProviderTableMeta.FILE_PATH, path);
135 }
136
137
138 public Vector<OCFile> getFolderContent(OCFile f) {
139 if (f != null && f.isFolder() && f.getFileId() != -1) {
140 return getFolderContent(f.getFileId());
141
142 } else {
143 return new Vector<OCFile>();
144 }
145 }
146
147
148 public Vector<OCFile> getFolderImages(OCFile folder) {
149 Vector<OCFile> ret = new Vector<OCFile>();
150 if (folder != null) {
151 // TODO better implementation, filtering in the access to database (if possible) instead of here
152 Vector<OCFile> tmp = getFolderContent(folder);
153 OCFile current = null;
154 for (int i=0; i<tmp.size(); i++) {
155 current = tmp.get(i);
156 if (current.isImage()) {
157 ret.add(current);
158 }
159 }
160 }
161 return ret;
162 }
163
164
165 public boolean saveFile(OCFile file) {
166 boolean overriden = false;
167 ContentValues cv = new ContentValues();
168 cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
169 cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
170 cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
171 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
172 cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
173 cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
174 //if (file.getParentId() != DataStorageManager.ROOT_PARENT_ID)
175 cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
176 cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
177 if (!file.isFolder())
178 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
179 cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
180 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
181 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
182 cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
183 cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
184 cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, file.isShareByLink() ? 1 : 0);
185 cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
186
187 boolean sameRemotePath = fileExists(file.getRemotePath());
188 if (sameRemotePath ||
189 fileExists(file.getFileId()) ) { // for renamed files; no more delete and create
190
191 OCFile oldFile = null;
192 if (sameRemotePath) {
193 oldFile = getFileByPath(file.getRemotePath());
194 file.setFileId(oldFile.getFileId());
195 } else {
196 oldFile = getFileById(file.getFileId());
197 }
198
199 overriden = true;
200 if (getContentResolver() != null) {
201 getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
202 ProviderTableMeta._ID + "=?",
203 new String[] { String.valueOf(file.getFileId()) });
204 } else {
205 try {
206 getContentProviderClient().update(ProviderTableMeta.CONTENT_URI,
207 cv, ProviderTableMeta._ID + "=?",
208 new String[] { String.valueOf(file.getFileId()) });
209 } catch (RemoteException e) {
210 Log_OC.e(TAG,
211 "Fail to insert insert file to database "
212 + e.getMessage());
213 }
214 }
215 } else {
216 Uri result_uri = null;
217 if (getContentResolver() != null) {
218 result_uri = getContentResolver().insert(
219 ProviderTableMeta.CONTENT_URI_FILE, cv);
220 } else {
221 try {
222 result_uri = getContentProviderClient().insert(
223 ProviderTableMeta.CONTENT_URI_FILE, cv);
224 } catch (RemoteException e) {
225 Log_OC.e(TAG,
226 "Fail to insert insert file to database "
227 + e.getMessage());
228 }
229 }
230 if (result_uri != null) {
231 long new_id = Long.parseLong(result_uri.getPathSegments()
232 .get(1));
233 file.setFileId(new_id);
234 }
235 }
236
237 if (file.isFolder()) {
238 updateFolderSize(file.getFileId());
239 } else {
240 updateFolderSize(file.getParentId());
241 }
242
243 return overriden;
244 }
245
246
247 /**
248 * Inserts or updates the list of files contained in a given folder.
249 *
250 * CALLER IS THE RESPONSIBLE FOR GRANTING RIGHT UPDATE OF INFORMATION, NOT THIS METHOD.
251 * HERE ONLY DATA CONSISTENCY SHOULD BE GRANTED
252 *
253 * @param folder
254 * @param files
255 * @param removeNotUpdated
256 */
257 public void saveFolder(OCFile folder, Collection<OCFile> updatedFiles, Collection<OCFile> filesToRemove) {
258
259 Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() + " children and " + filesToRemove.size() + " files to remove");
260
261 ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(updatedFiles.size());
262
263 // prepare operations to insert or update files to save in the given folder
264 for (OCFile file : updatedFiles) {
265 ContentValues cv = new ContentValues();
266 cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
267 cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
268 cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
269 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
270 cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
271 cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
272 //cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
273 cv.put(ProviderTableMeta.FILE_PARENT, folder.getFileId());
274 cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
275 if (!file.isFolder()) {
276 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
277 }
278 cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
279 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
280 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
281 cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
282 cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
283 cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, file.isShareByLink() ? 1 : 0);
284 cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
285
286 boolean existsByPath = fileExists(file.getRemotePath());
287 if (existsByPath || fileExists(file.getFileId())) {
288 // updating an existing file
289 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
290 withValues(cv).
291 withSelection( ProviderTableMeta._ID + "=?",
292 new String[] { String.valueOf(file.getFileId()) })
293 .build());
294
295 } else {
296 // adding a new file
297 operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
298 }
299 }
300
301 // prepare operations to remove files in the given folder
302 String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
303 String [] whereArgs = null;
304 for (OCFile file : filesToRemove) {
305 if (file.getParentId() == folder.getFileId()) {
306 whereArgs = new String[]{mAccount.name, file.getRemotePath()};
307 //Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, "" + file.getFileId());
308 if (file.isFolder()) {
309 operations.add(ContentProviderOperation
310 .newDelete(ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_DIR, file.getFileId())).withSelection(where, whereArgs)
311 .build());
312 // TODO remove local folder
313 } else {
314 operations.add(ContentProviderOperation
315 .newDelete(ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, file.getFileId())).withSelection(where, whereArgs)
316 .build());
317 if (file.isDown()) {
318 new File(file.getStoragePath()).delete();
319 // TODO move the deletion of local contents after success of deletions
320 }
321 }
322 }
323 }
324
325 // update metadata of folder
326 ContentValues cv = new ContentValues();
327 cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp());
328 cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, folder.getModificationTimestampAtLastSyncForData());
329 cv.put(ProviderTableMeta.FILE_CREATION, folder.getCreationTimestamp());
330 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0); // FileContentProvider calculates the right size
331 cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimetype());
332 cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
333 cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
334 cv.put(ProviderTableMeta.FILE_PATH, folder.getRemotePath());
335 cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
336 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, folder.getLastSyncDateForProperties());
337 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
338 cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, folder.keepInSync() ? 1 : 0);
339 cv.put(ProviderTableMeta.FILE_ETAG, folder.getEtag());
340 cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, folder.isShareByLink() ? 1 : 0);
341 cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, folder.getPublicLink());
342
343 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
344 withValues(cv).
345 withSelection( ProviderTableMeta._ID + "=?",
346 new String[] { String.valueOf(folder.getFileId()) })
347 .build());
348
349 // apply operations in batch
350 ContentProviderResult[] results = null;
351 Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
352 try {
353 if (getContentResolver() != null) {
354 results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
355
356 } else {
357 results = getContentProviderClient().applyBatch(operations);
358 }
359
360 } catch (OperationApplicationException e) {
361 Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
362
363 } catch (RemoteException e) {
364 Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
365 }
366
367 // update new id in file objects for insertions
368 if (results != null) {
369 long newId;
370 Iterator<OCFile> filesIt = updatedFiles.iterator();
371 OCFile file = null;
372 for (int i=0; i<results.length; i++) {
373 if (filesIt.hasNext()) {
374 file = filesIt.next();
375 } else {
376 file = null;
377 }
378 if (results[i].uri != null) {
379 newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
380 //updatedFiles.get(i).setFileId(newId);
381 if (file != null) {
382 file.setFileId(newId);
383 }
384 }
385 }
386 }
387
388 updateFolderSize(folder.getFileId());
389
390 }
391
392
393 /**
394 *
395 * @param id
396 */
397 private void updateFolderSize(long id) {
398 if (id > FileDataStorageManager.ROOT_PARENT_ID) {
399 Log_OC.d(TAG, "Updating size of " + id);
400 if (getContentResolver() != null) {
401 getContentResolver().update(ProviderTableMeta.CONTENT_URI_DIR,
402 new ContentValues(), // won't be used, but cannot be null; crashes in KLP
403 ProviderTableMeta._ID + "=?",
404 new String[] { String.valueOf(id) });
405 } else {
406 try {
407 getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_DIR,
408 new ContentValues(), // won't be used, but cannot be null; crashes in KLP
409 ProviderTableMeta._ID + "=?",
410 new String[] { String.valueOf(id) });
411
412 } catch (RemoteException e) {
413 Log_OC.e(TAG, "Exception in update of folder size through compatibility patch " + e.getMessage());
414 }
415 }
416 } else {
417 Log_OC.e(TAG, "not updating size for folder " + id);
418 }
419 }
420
421
422 public void removeFile(OCFile file, boolean removeDBData, boolean removeLocalCopy) {
423 if (file != null) {
424 if (file.isFolder()) {
425 removeFolder(file, removeDBData, removeLocalCopy);
426
427 } else {
428 if (removeDBData) {
429 //Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
430 Uri file_uri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, file.getFileId());
431 String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
432 String [] whereArgs = new String[]{mAccount.name, file.getRemotePath()};
433 if (getContentProviderClient() != null) {
434 try {
435 getContentProviderClient().delete(file_uri, where, whereArgs);
436 } catch (RemoteException e) {
437 e.printStackTrace();
438 }
439 } else {
440 getContentResolver().delete(file_uri, where, whereArgs);
441 }
442 updateFolderSize(file.getParentId());
443 }
444 if (removeLocalCopy && file.isDown() && file.getStoragePath() != null) {
445 boolean success = new File(file.getStoragePath()).delete();
446 if (!removeDBData && success) {
447 // maybe unnecessary, but should be checked TODO remove if unnecessary
448 file.setStoragePath(null);
449 saveFile(file);
450 }
451 }
452 }
453 }
454 }
455
456
457 public void removeFolder(OCFile folder, boolean removeDBData, boolean removeLocalContent) {
458 if (folder != null && folder.isFolder()) {
459 if (removeDBData && folder.getFileId() != -1) {
460 removeFolderInDb(folder);
461 }
462 if (removeLocalContent) {
463 File localFolder = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, folder));
464 removeLocalFolder(localFolder);
465 }
466 }
467 }
468
469 private void removeFolderInDb(OCFile folder) {
470 Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, ""+ folder.getFileId()); // URI for recursive deletion
471 String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
472 String [] whereArgs = new String[]{mAccount.name, folder.getRemotePath()};
473 if (getContentProviderClient() != null) {
474 try {
475 getContentProviderClient().delete(folder_uri, where, whereArgs);
476 } catch (RemoteException e) {
477 e.printStackTrace();
478 }
479 } else {
480 getContentResolver().delete(folder_uri, where, whereArgs);
481 }
482 updateFolderSize(folder.getParentId());
483 }
484
485 private void removeLocalFolder(File folder) {
486 if (folder.exists()) {
487 File[] files = folder.listFiles();
488 if (files != null) {
489 for (File file : files) {
490 if (file.isDirectory()) {
491 removeLocalFolder(file);
492 } else {
493 file.delete();
494 }
495 }
496 }
497 folder.delete();
498 }
499 }
500
501 /**
502 * Updates database for a folder that was moved to a different location.
503 *
504 * TODO explore better (faster) implementations
505 * TODO throw exceptions up !
506 */
507 public void moveFolder(OCFile folder, String newPath) {
508 // TODO check newPath
509
510 if (folder != null && folder.isFolder() && folder.fileExists() && !OCFile.ROOT_PATH.equals(folder.getFileName())) {
511 /// 1. get all the descendants of 'dir' in a single QUERY (including 'dir')
512 Cursor c = null;
513 if (getContentProviderClient() != null) {
514 try {
515 c = getContentProviderClient().query(ProviderTableMeta.CONTENT_URI,
516 null,
517 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ? ",
518 new String[] { mAccount.name, folder.getRemotePath() + "%" }, ProviderTableMeta.FILE_PATH + " ASC ");
519 } catch (RemoteException e) {
520 Log_OC.e(TAG, e.getMessage());
521 }
522 } else {
523 c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
524 null,
525 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ? ",
526 new String[] { mAccount.name, folder.getRemotePath() + "%" }, ProviderTableMeta.FILE_PATH + " ASC ");
527 }
528
529 /// 2. prepare a batch of update operations to change all the descendants
530 ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(c.getCount());
531 int lengthOfOldPath = folder.getRemotePath().length();
532 String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name);
533 int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath;
534 if (c.moveToFirst()) {
535 do {
536 ContentValues cv = new ContentValues(); // don't take the constructor out of the loop and clear the object
537 OCFile child = createFileInstance(c);
538 cv.put(ProviderTableMeta.FILE_PATH, newPath + child.getRemotePath().substring(lengthOfOldPath));
539 if (child.getStoragePath() != null && child.getStoragePath().startsWith(defaultSavePath)) {
540 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, defaultSavePath + newPath + child.getStoragePath().substring(lengthOfOldStoragePath));
541 }
542 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
543 withValues(cv).
544 withSelection( ProviderTableMeta._ID + "=?",
545 new String[] { String.valueOf(child.getFileId()) })
546 .build());
547 } while (c.moveToNext());
548 }
549 c.close();
550
551 /// 3. apply updates in batch
552 try {
553 if (getContentResolver() != null) {
554 getContentResolver().applyBatch(MainApp.getAuthority(), operations);
555
556 } else {
557 getContentProviderClient().applyBatch(operations);
558 }
559
560 } catch (OperationApplicationException e) {
561 Log_OC.e(TAG, "Fail to update descendants of " + folder.getFileId() + " in database", e);
562
563 } catch (RemoteException e) {
564 Log_OC.e(TAG, "Fail to update desendants of " + folder.getFileId() + " in database", e);
565 }
566
567 }
568 }
569
570
571 private Vector<OCFile> getFolderContent(long parentId) {
572
573 Vector<OCFile> ret = new Vector<OCFile>();
574
575 Uri req_uri = Uri.withAppendedPath(
576 ProviderTableMeta.CONTENT_URI_DIR,
577 String.valueOf(parentId));
578 Cursor c = null;
579
580 if (getContentProviderClient() != null) {
581 try {
582 c = getContentProviderClient().query(req_uri, null,
583 ProviderTableMeta.FILE_PARENT + "=?" ,
584 new String[] { String.valueOf(parentId)}, null);
585 } catch (RemoteException e) {
586 Log_OC.e(TAG, e.getMessage());
587 return ret;
588 }
589 } else {
590 c = getContentResolver().query(req_uri, null,
591 ProviderTableMeta.FILE_PARENT + "=?" ,
592 new String[] { String.valueOf(parentId)}, null);
593 }
594
595 if (c.moveToFirst()) {
596 do {
597 OCFile child = createFileInstance(c);
598 ret.add(child);
599 } while (c.moveToNext());
600 }
601
602 c.close();
603
604 Collections.sort(ret);
605
606 return ret;
607 }
608
609
610 private OCFile createRootDir() {
611 OCFile file = new OCFile(OCFile.ROOT_PATH);
612 file.setMimetype("DIR");
613 file.setParentId(FileDataStorageManager.ROOT_PARENT_ID);
614 saveFile(file);
615 return file;
616 }
617
618 private boolean fileExists(String cmp_key, String value) {
619 Cursor c;
620 if (getContentResolver() != null) {
621 c = getContentResolver()
622 .query(ProviderTableMeta.CONTENT_URI,
623 null,
624 cmp_key + "=? AND "
625 + ProviderTableMeta.FILE_ACCOUNT_OWNER
626 + "=?",
627 new String[] { value, mAccount.name }, null);
628 } else {
629 try {
630 c = getContentProviderClient().query(
631 ProviderTableMeta.CONTENT_URI,
632 null,
633 cmp_key + "=? AND "
634 + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
635 new String[] { value, mAccount.name }, null);
636 } catch (RemoteException e) {
637 Log_OC.e(TAG,
638 "Couldn't determine file existance, assuming non existance: "
639 + e.getMessage());
640 return false;
641 }
642 }
643 boolean retval = c.moveToFirst();
644 c.close();
645 return retval;
646 }
647
648 private Cursor getCursorForValue(String key, String value) {
649 Cursor c = null;
650 if (getContentResolver() != null) {
651 c = getContentResolver()
652 .query(ProviderTableMeta.CONTENT_URI,
653 null,
654 key + "=? AND "
655 + ProviderTableMeta.FILE_ACCOUNT_OWNER
656 + "=?",
657 new String[] { value, mAccount.name }, null);
658 } else {
659 try {
660 c = getContentProviderClient().query(
661 ProviderTableMeta.CONTENT_URI,
662 null,
663 key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER
664 + "=?", new String[] { value, mAccount.name },
665 null);
666 } catch (RemoteException e) {
667 Log_OC.e(TAG, "Could not get file details: " + e.getMessage());
668 c = null;
669 }
670 }
671 return c;
672 }
673
674 private OCFile createFileInstance(Cursor c) {
675 OCFile file = null;
676 if (c != null) {
677 file = new OCFile(c.getString(c
678 .getColumnIndex(ProviderTableMeta.FILE_PATH)));
679 file.setFileId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
680 file.setParentId(c.getLong(c
681 .getColumnIndex(ProviderTableMeta.FILE_PARENT)));
682 file.setMimetype(c.getString(c
683 .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
684 if (!file.isFolder()) {
685 file.setStoragePath(c.getString(c
686 .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
687 if (file.getStoragePath() == null) {
688 // try to find existing file and bind it with current account; - with the current update of SynchronizeFolderOperation, this won't be necessary anymore after a full synchronization of the account
689 File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
690 if (f.exists()) {
691 file.setStoragePath(f.getAbsolutePath());
692 file.setLastSyncDateForData(f.lastModified());
693 }
694 }
695 }
696 file.setFileLength(c.getLong(c
697 .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)));
698 file.setCreationTimestamp(c.getLong(c
699 .getColumnIndex(ProviderTableMeta.FILE_CREATION)));
700 file.setModificationTimestamp(c.getLong(c
701 .getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
702 file.setModificationTimestampAtLastSyncForData(c.getLong(c
703 .getColumnIndex(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA)));
704 file.setLastSyncDateForProperties(c.getLong(c
705 .getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
706 file.setLastSyncDateForData(c.getLong(c.
707 getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA)));
708 file.setKeepInSync(c.getInt(
709 c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
710 file.setEtag(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG)));
711 file.setShareByLink(c.getInt(
712 c.getColumnIndex(ProviderTableMeta.FILE_SHARE_BY_LINK)) == 1 ? true : false);
713 file.setPublicLink(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PUBLIC_LINK)));
714
715 }
716 return file;
717 }
718
719 }