OC-2332: rewrite getAvailableRemotePath from UpdateFileOperation, using ExistenceCehe...
[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
185 boolean sameRemotePath = fileExists(file.getRemotePath());
186 if (sameRemotePath ||
187 fileExists(file.getFileId()) ) { // for renamed files; no more delete and create
188
189 OCFile oldFile = null;
190 if (sameRemotePath) {
191 oldFile = getFileByPath(file.getRemotePath());
192 file.setFileId(oldFile.getFileId());
193 } else {
194 oldFile = getFileById(file.getFileId());
195 }
196
197 overriden = true;
198 if (getContentResolver() != null) {
199 getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
200 ProviderTableMeta._ID + "=?",
201 new String[] { String.valueOf(file.getFileId()) });
202 } else {
203 try {
204 getContentProviderClient().update(ProviderTableMeta.CONTENT_URI,
205 cv, ProviderTableMeta._ID + "=?",
206 new String[] { String.valueOf(file.getFileId()) });
207 } catch (RemoteException e) {
208 Log_OC.e(TAG,
209 "Fail to insert insert file to database "
210 + e.getMessage());
211 }
212 }
213 } else {
214 Uri result_uri = null;
215 if (getContentResolver() != null) {
216 result_uri = getContentResolver().insert(
217 ProviderTableMeta.CONTENT_URI_FILE, cv);
218 } else {
219 try {
220 result_uri = getContentProviderClient().insert(
221 ProviderTableMeta.CONTENT_URI_FILE, cv);
222 } catch (RemoteException e) {
223 Log_OC.e(TAG,
224 "Fail to insert insert file to database "
225 + e.getMessage());
226 }
227 }
228 if (result_uri != null) {
229 long new_id = Long.parseLong(result_uri.getPathSegments()
230 .get(1));
231 file.setFileId(new_id);
232 }
233 }
234
235 if (file.isFolder()) {
236 updateFolderSize(file.getFileId());
237 } else {
238 updateFolderSize(file.getParentId());
239 }
240
241 return overriden;
242 }
243
244
245 /**
246 * Inserts or updates the list of files contained in a given folder.
247 *
248 * CALLER IS THE RESPONSIBLE FOR GRANTING RIGHT UPDATE OF INFORMATION, NOT THIS METHOD.
249 * HERE ONLY DATA CONSISTENCY SHOULD BE GRANTED
250 *
251 * @param folder
252 * @param files
253 * @param removeNotUpdated
254 */
255 public void saveFolder(OCFile folder, Collection<OCFile> updatedFiles, Collection<OCFile> filesToRemove) {
256
257 Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() + " children and " + filesToRemove.size() + " files to remove");
258
259 ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(updatedFiles.size());
260
261 // prepare operations to insert or update files to save in the given folder
262 for (OCFile file : updatedFiles) {
263 ContentValues cv = new ContentValues();
264 cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
265 cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
266 cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
267 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
268 cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
269 cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
270 //cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
271 cv.put(ProviderTableMeta.FILE_PARENT, folder.getFileId());
272 cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
273 if (!file.isFolder()) {
274 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
275 }
276 cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
277 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
278 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
279 cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
280 cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
281
282 boolean existsByPath = fileExists(file.getRemotePath());
283 if (existsByPath || fileExists(file.getFileId())) {
284 // updating an existing file
285 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
286 withValues(cv).
287 withSelection( ProviderTableMeta._ID + "=?",
288 new String[] { String.valueOf(file.getFileId()) })
289 .build());
290
291 } else {
292 // adding a new file
293 operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
294 }
295 }
296
297 // prepare operations to remove files in the given folder
298 String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
299 String [] whereArgs = null;
300 for (OCFile file : filesToRemove) {
301 if (file.getParentId() == folder.getFileId()) {
302 whereArgs = new String[]{mAccount.name, file.getRemotePath()};
303 //Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, "" + file.getFileId());
304 if (file.isFolder()) {
305 operations.add(ContentProviderOperation
306 .newDelete(ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_DIR, file.getFileId())).withSelection(where, whereArgs)
307 .build());
308 // TODO remove local folder
309 } else {
310 operations.add(ContentProviderOperation
311 .newDelete(ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, file.getFileId())).withSelection(where, whereArgs)
312 .build());
313 if (file.isDown()) {
314 new File(file.getStoragePath()).delete();
315 // TODO move the deletion of local contents after success of deletions
316 }
317 }
318 }
319 }
320
321 // update metadata of folder
322 ContentValues cv = new ContentValues();
323 cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp());
324 cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, folder.getModificationTimestampAtLastSyncForData());
325 cv.put(ProviderTableMeta.FILE_CREATION, folder.getCreationTimestamp());
326 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0); // FileContentProvider calculates the right size
327 cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimetype());
328 cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
329 cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
330 cv.put(ProviderTableMeta.FILE_PATH, folder.getRemotePath());
331 cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
332 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, folder.getLastSyncDateForProperties());
333 cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
334 cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, folder.keepInSync() ? 1 : 0);
335 cv.put(ProviderTableMeta.FILE_ETAG, folder.getEtag());
336 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
337 withValues(cv).
338 withSelection( ProviderTableMeta._ID + "=?",
339 new String[] { String.valueOf(folder.getFileId()) })
340 .build());
341
342 // apply operations in batch
343 ContentProviderResult[] results = null;
344 Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
345 try {
346 if (getContentResolver() != null) {
347 results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
348
349 } else {
350 results = getContentProviderClient().applyBatch(operations);
351 }
352
353 } catch (OperationApplicationException e) {
354 Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
355
356 } catch (RemoteException e) {
357 Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
358 }
359
360 // update new id in file objects for insertions
361 if (results != null) {
362 long newId;
363 Iterator<OCFile> filesIt = updatedFiles.iterator();
364 OCFile file = null;
365 for (int i=0; i<results.length; i++) {
366 if (filesIt.hasNext()) {
367 file = filesIt.next();
368 } else {
369 file = null;
370 }
371 if (results[i].uri != null) {
372 newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
373 //updatedFiles.get(i).setFileId(newId);
374 if (file != null) {
375 file.setFileId(newId);
376 }
377 }
378 }
379 }
380
381 updateFolderSize(folder.getFileId());
382
383 }
384
385
386 /**
387 *
388 * @param id
389 */
390 private void updateFolderSize(long id) {
391 if (id > FileDataStorageManager.ROOT_PARENT_ID) {
392 Log_OC.d(TAG, "Updating size of " + id);
393 if (getContentResolver() != null) {
394 getContentResolver().update(ProviderTableMeta.CONTENT_URI_DIR,
395 new ContentValues(), // won't be used, but cannot be null; crashes in KLP
396 ProviderTableMeta._ID + "=?",
397 new String[] { String.valueOf(id) });
398 } else {
399 try {
400 getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_DIR,
401 new ContentValues(), // won't be used, but cannot be null; crashes in KLP
402 ProviderTableMeta._ID + "=?",
403 new String[] { String.valueOf(id) });
404
405 } catch (RemoteException e) {
406 Log_OC.e(TAG, "Exception in update of folder size through compatibility patch " + e.getMessage());
407 }
408 }
409 } else {
410 Log_OC.e(TAG, "not updating size for folder " + id);
411 }
412 }
413
414
415 public void removeFile(OCFile file, boolean removeDBData, boolean removeLocalCopy) {
416 if (file != null) {
417 if (file.isFolder()) {
418 removeFolder(file, removeDBData, removeLocalCopy);
419
420 } else {
421 if (removeDBData) {
422 //Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
423 Uri file_uri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, file.getFileId());
424 String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
425 String [] whereArgs = new String[]{mAccount.name, file.getRemotePath()};
426 if (getContentProviderClient() != null) {
427 try {
428 getContentProviderClient().delete(file_uri, where, whereArgs);
429 } catch (RemoteException e) {
430 e.printStackTrace();
431 }
432 } else {
433 getContentResolver().delete(file_uri, where, whereArgs);
434 }
435 updateFolderSize(file.getParentId());
436 }
437 if (removeLocalCopy && file.isDown() && file.getStoragePath() != null) {
438 boolean success = new File(file.getStoragePath()).delete();
439 if (!removeDBData && success) {
440 // maybe unnecessary, but should be checked TODO remove if unnecessary
441 file.setStoragePath(null);
442 saveFile(file);
443 }
444 }
445 }
446 }
447 }
448
449
450 public void removeFolder(OCFile folder, boolean removeDBData, boolean removeLocalContent) {
451 if (folder != null && folder.isFolder()) {
452 if (removeDBData && folder.getFileId() != -1) {
453 removeFolderInDb(folder);
454 }
455 if (removeLocalContent) {
456 File localFolder = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, folder));
457 removeLocalFolder(localFolder);
458 }
459 }
460 }
461
462 private void removeFolderInDb(OCFile folder) {
463 Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, ""+ folder.getFileId()); // URI for recursive deletion
464 String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
465 String [] whereArgs = new String[]{mAccount.name, folder.getRemotePath()};
466 if (getContentProviderClient() != null) {
467 try {
468 getContentProviderClient().delete(folder_uri, where, whereArgs);
469 } catch (RemoteException e) {
470 e.printStackTrace();
471 }
472 } else {
473 getContentResolver().delete(folder_uri, where, whereArgs);
474 }
475 updateFolderSize(folder.getParentId());
476 }
477
478 private void removeLocalFolder(File folder) {
479 if (folder.exists()) {
480 File[] files = folder.listFiles();
481 if (files != null) {
482 for (File file : files) {
483 if (file.isDirectory()) {
484 removeLocalFolder(file);
485 } else {
486 file.delete();
487 }
488 }
489 }
490 folder.delete();
491 }
492 }
493
494 /**
495 * Updates database for a folder that was moved to a different location.
496 *
497 * TODO explore better (faster) implementations
498 * TODO throw exceptions up !
499 */
500 public void moveFolder(OCFile folder, String newPath) {
501 // TODO check newPath
502
503 if (folder != null && folder.isFolder() && folder.fileExists() && !OCFile.ROOT_PATH.equals(folder.getFileName())) {
504 /// 1. get all the descendants of 'dir' in a single QUERY (including 'dir')
505 Cursor c = null;
506 if (getContentProviderClient() != null) {
507 try {
508 c = getContentProviderClient().query(ProviderTableMeta.CONTENT_URI,
509 null,
510 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ? ",
511 new String[] { mAccount.name, folder.getRemotePath() + "%" }, ProviderTableMeta.FILE_PATH + " ASC ");
512 } catch (RemoteException e) {
513 Log_OC.e(TAG, e.getMessage());
514 }
515 } else {
516 c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
517 null,
518 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ? ",
519 new String[] { mAccount.name, folder.getRemotePath() + "%" }, ProviderTableMeta.FILE_PATH + " ASC ");
520 }
521
522 /// 2. prepare a batch of update operations to change all the descendants
523 ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(c.getCount());
524 int lengthOfOldPath = folder.getRemotePath().length();
525 String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name);
526 int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath;
527 if (c.moveToFirst()) {
528 do {
529 ContentValues cv = new ContentValues(); // don't take the constructor out of the loop and clear the object
530 OCFile child = createFileInstance(c);
531 cv.put(ProviderTableMeta.FILE_PATH, newPath + child.getRemotePath().substring(lengthOfOldPath));
532 if (child.getStoragePath() != null && child.getStoragePath().startsWith(defaultSavePath)) {
533 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, defaultSavePath + newPath + child.getStoragePath().substring(lengthOfOldStoragePath));
534 }
535 operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
536 withValues(cv).
537 withSelection( ProviderTableMeta._ID + "=?",
538 new String[] { String.valueOf(child.getFileId()) })
539 .build());
540 } while (c.moveToNext());
541 }
542 c.close();
543
544 /// 3. apply updates in batch
545 try {
546 if (getContentResolver() != null) {
547 getContentResolver().applyBatch(MainApp.getAuthority(), operations);
548
549 } else {
550 getContentProviderClient().applyBatch(operations);
551 }
552
553 } catch (OperationApplicationException e) {
554 Log_OC.e(TAG, "Fail to update descendants of " + folder.getFileId() + " in database", e);
555
556 } catch (RemoteException e) {
557 Log_OC.e(TAG, "Fail to update desendants of " + folder.getFileId() + " in database", e);
558 }
559
560 }
561 }
562
563
564 private Vector<OCFile> getFolderContent(long parentId) {
565
566 Vector<OCFile> ret = new Vector<OCFile>();
567
568 Uri req_uri = Uri.withAppendedPath(
569 ProviderTableMeta.CONTENT_URI_DIR,
570 String.valueOf(parentId));
571 Cursor c = null;
572
573 if (getContentProviderClient() != null) {
574 try {
575 c = getContentProviderClient().query(req_uri, null,
576 ProviderTableMeta.FILE_PARENT + "=?" ,
577 new String[] { String.valueOf(parentId)}, null);
578 } catch (RemoteException e) {
579 Log_OC.e(TAG, e.getMessage());
580 return ret;
581 }
582 } else {
583 c = getContentResolver().query(req_uri, null,
584 ProviderTableMeta.FILE_PARENT + "=?" ,
585 new String[] { String.valueOf(parentId)}, null);
586 }
587
588 if (c.moveToFirst()) {
589 do {
590 OCFile child = createFileInstance(c);
591 ret.add(child);
592 } while (c.moveToNext());
593 }
594
595 c.close();
596
597 Collections.sort(ret);
598
599 return ret;
600 }
601
602
603 private OCFile createRootDir() {
604 OCFile file = new OCFile(OCFile.ROOT_PATH);
605 file.setMimetype("DIR");
606 file.setParentId(FileDataStorageManager.ROOT_PARENT_ID);
607 saveFile(file);
608 return file;
609 }
610
611 private boolean fileExists(String cmp_key, String value) {
612 Cursor c;
613 if (getContentResolver() != null) {
614 c = getContentResolver()
615 .query(ProviderTableMeta.CONTENT_URI,
616 null,
617 cmp_key + "=? AND "
618 + ProviderTableMeta.FILE_ACCOUNT_OWNER
619 + "=?",
620 new String[] { value, mAccount.name }, null);
621 } else {
622 try {
623 c = getContentProviderClient().query(
624 ProviderTableMeta.CONTENT_URI,
625 null,
626 cmp_key + "=? AND "
627 + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
628 new String[] { value, mAccount.name }, null);
629 } catch (RemoteException e) {
630 Log_OC.e(TAG,
631 "Couldn't determine file existance, assuming non existance: "
632 + e.getMessage());
633 return false;
634 }
635 }
636 boolean retval = c.moveToFirst();
637 c.close();
638 return retval;
639 }
640
641 private Cursor getCursorForValue(String key, String value) {
642 Cursor c = null;
643 if (getContentResolver() != null) {
644 c = getContentResolver()
645 .query(ProviderTableMeta.CONTENT_URI,
646 null,
647 key + "=? AND "
648 + ProviderTableMeta.FILE_ACCOUNT_OWNER
649 + "=?",
650 new String[] { value, mAccount.name }, null);
651 } else {
652 try {
653 c = getContentProviderClient().query(
654 ProviderTableMeta.CONTENT_URI,
655 null,
656 key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER
657 + "=?", new String[] { value, mAccount.name },
658 null);
659 } catch (RemoteException e) {
660 Log_OC.e(TAG, "Could not get file details: " + e.getMessage());
661 c = null;
662 }
663 }
664 return c;
665 }
666
667 private OCFile createFileInstance(Cursor c) {
668 OCFile file = null;
669 if (c != null) {
670 file = new OCFile(c.getString(c
671 .getColumnIndex(ProviderTableMeta.FILE_PATH)));
672 file.setFileId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
673 file.setParentId(c.getLong(c
674 .getColumnIndex(ProviderTableMeta.FILE_PARENT)));
675 file.setMimetype(c.getString(c
676 .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
677 if (!file.isFolder()) {
678 file.setStoragePath(c.getString(c
679 .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
680 if (file.getStoragePath() == null) {
681 // 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
682 File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
683 if (f.exists()) {
684 file.setStoragePath(f.getAbsolutePath());
685 file.setLastSyncDateForData(f.lastModified());
686 }
687 }
688 }
689 file.setFileLength(c.getLong(c
690 .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)));
691 file.setCreationTimestamp(c.getLong(c
692 .getColumnIndex(ProviderTableMeta.FILE_CREATION)));
693 file.setModificationTimestamp(c.getLong(c
694 .getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
695 file.setModificationTimestampAtLastSyncForData(c.getLong(c
696 .getColumnIndex(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA)));
697 file.setLastSyncDateForProperties(c.getLong(c
698 .getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
699 file.setLastSyncDateForData(c.getLong(c.
700 getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA)));
701 file.setKeepInSync(c.getInt(
702 c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
703 file.setEtag(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_ETAG)));
704
705 }
706 return file;
707 }
708
709 }