Code cleanup: Code documentation, formatting, variable names etc were
[pub/Android/ownCloud.git] / src / eu / alefzero / owncloud / datamodel / OCFile.java
1 /* ownCloud Android client application
2 * Copyright (C) 2012 Bartek Przybylski
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
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 eu.alefzero.owncloud.datamodel;
20
21 import java.io.File;
22 import java.util.Vector;
23
24 import android.accounts.Account;
25 import android.content.ContentProviderClient;
26 import android.content.ContentResolver;
27 import android.content.ContentValues;
28 import android.database.Cursor;
29 import android.net.Uri;
30 import android.os.RemoteException;
31 import android.util.Log;
32 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
33
34 public class OCFile {
35 private static String TAG = "OCFile";
36
37 private long id_;
38 private long parent_id_;
39 private long length_;
40 private long creation_timestamp_;
41 private long modified_timestamp_;
42 private String path_;
43 private String storage_path_;
44 private String mimetype_;
45
46 private ContentResolver contentResolver_;
47 private ContentProviderClient providerClient_;
48 private Account account_;
49
50 private OCFile(ContentProviderClient providerClient, Account account) {
51 account_ = account;
52 providerClient_ = providerClient;
53 resetData();
54 }
55
56 private OCFile(ContentResolver contentResolver, Account account) {
57 account_ = account;
58 contentResolver_ = contentResolver;
59 resetData();
60 }
61
62 /**
63 * Query the database for a {@link OCFile} belonging to a given account
64 * and id.
65 *
66 * @param resolver The {@link ContentResolver} to use
67 * @param account The {@link Account} the {@link OCFile} belongs to
68 * @param id The ID the file has in the database
69 */
70 public OCFile(ContentResolver resolver, Account account, long id) {
71 contentResolver_ = resolver;
72 account_ = account;
73 Cursor c = contentResolver_.query(ProviderTableMeta.CONTENT_URI_FILE,
74 null, ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "
75 + ProviderTableMeta._ID + "=?", new String[] {
76 account_.name, String.valueOf(id) }, null);
77 if (c.moveToFirst())
78 setFileData(c);
79 }
80
81 /**
82 * Query the database for a {@link OCFile} belonging to a given account
83 * and that matches remote path
84 *
85 * @param contentResolver The {@link ContentResolver} to use
86 * @param account The {@link Account} the {@link OCFile} belongs to
87 * @param path The remote path of the file
88 */
89 public OCFile(ContentResolver contentResolver, Account account, String path) {
90 contentResolver_ = contentResolver;
91 account_ = account;
92
93 Cursor c = contentResolver_.query(ProviderTableMeta.CONTENT_URI_FILE,
94 null, ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "
95 + ProviderTableMeta.FILE_PATH + "=?", new String[] {
96 account_.name, path }, null);
97 if (c.moveToFirst()) {
98 setFileData(c);
99 if (path_ != null)
100 path_ = path;
101 }
102 }
103
104 public OCFile(ContentProviderClient cp, Account account, String path) {
105 providerClient_ = cp;
106 account_ = account;
107
108 try {
109 Cursor c = providerClient_.query(ProviderTableMeta.CONTENT_URI_FILE, null,
110 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "
111 + ProviderTableMeta.FILE_PATH + "=?", new String[] {
112 account_.name, path }, null);
113 if (c.moveToFirst()) {
114 setFileData(c);
115 if (path_ != null)
116 path_ = path;
117 }
118 } catch (RemoteException e) {
119 Log.d(TAG, e.getMessage());
120 }
121 }
122
123 /**
124 * Creates a new {@link OCFile}
125 *
126 * @param providerClient The {@link ContentProviderClient} to use
127 * @param account The {@link Account} that this file belongs to
128 * @param path The remote path
129 * @param length The file size in bytes
130 * @param creation_timestamp The UNIX timestamp of the creation date
131 * @param modified_timestamp The UNIX timestamp of the modification date
132 * @param mimetype The mimetype to set
133 * @param parent_id The parent folder of that file
134 * @return A new instance of {@link OCFile}
135 */
136 public static OCFile createNewFile(ContentProviderClient providerClient,
137 Account account, String path, long length, long creation_timestamp,
138 long modified_timestamp, String mimetype, long parent_id) {
139 OCFile new_file = new OCFile(providerClient, account);
140
141 try {
142 Cursor c = new_file.providerClient_.query(ProviderTableMeta.CONTENT_URI_FILE,
143 null, ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "
144 + ProviderTableMeta.FILE_PATH + "=?", new String[] {
145 new_file.account_.name, path }, null);
146 if (c.moveToFirst())
147 new_file.setFileData(c);
148 c.close();
149 } catch (RemoteException e) {
150 Log.e(TAG, e.getMessage());
151 }
152
153 new_file.path_ = path;
154 new_file.length_ = length;
155 new_file.creation_timestamp_ = creation_timestamp;
156 new_file.modified_timestamp_ = modified_timestamp;
157 new_file.mimetype_ = mimetype;
158 new_file.parent_id_ = parent_id;
159
160 return new_file;
161 }
162
163 /**
164 * Creates a new {@link OCFile}
165 *
166 * @param contentResolver The {@link ContentResolver} to use
167 * @param account The {@link Account} that this file belongs to
168 * @param path The remote path
169 * @param length The file size in bytes
170 * @param creation_timestamp The UNIX timestamp of the creation date
171 * @param modified_timestamp The UNIX timestamp of the modification date
172 * @param mimetype The mimetype to set
173 * @param parent_id The parent folder of that file
174 * @return A new instance of {@link OCFile}
175 */
176 public static OCFile createNewFile(ContentResolver contentResolver,
177 Account account, String path, int length, int creation_timestamp,
178 int modified_timestamp, String mimetype, long parent_id) {
179 OCFile new_file = new OCFile(contentResolver, account);
180 Cursor c = new_file.contentResolver_.query(
181 ProviderTableMeta.CONTENT_URI_FILE, null,
182 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "
183 + ProviderTableMeta.FILE_PATH + "=?", new String[] {
184 new_file.account_.name, path }, null);
185 if (c.moveToFirst())
186 new_file.setFileData(c);
187 c.close();
188
189 new_file.path_ = path;
190 new_file.length_ = length;
191 new_file.creation_timestamp_ = creation_timestamp;
192 new_file.modified_timestamp_ = modified_timestamp;
193 new_file.mimetype_ = mimetype;
194 new_file.parent_id_ = parent_id;
195
196 return new_file;
197 }
198
199
200 /**
201 * Gets the ID of the file
202 *
203 * @return the file ID
204 */
205 public long getFileId() {
206 return id_;
207 }
208
209 /**
210 * Returns the path of the file
211 *
212 * @return The path
213 */
214 public String getPath() {
215 return path_;
216 }
217
218 /**
219 * Can be used to check, whether or not this file exists in the database
220 * already
221 *
222 * @return true, if the file exists in the database
223 */
224 public boolean fileExists() {
225 return id_ != -1;
226 }
227
228 /**
229 * Use this to find out if this file is a Directory
230 *
231 * @return true if it is a directory
232 */
233 public boolean isDirectory() {
234 return mimetype_ != null && mimetype_.equals("DIR");
235 }
236
237 /**
238 * Use this to check if this file is available locally
239 *
240 * @return true if it is
241 */
242 public boolean isDownloaded() {
243 return storage_path_ != null;
244 }
245
246 /**
247 * The path, where the file is stored locally
248 *
249 * @return The local path to the file
250 */
251 public String getStoragePath() {
252 return storage_path_;
253 }
254
255 /**
256 * Can be used to set the path where the file is stored
257 *
258 * @param storage_path
259 * to set
260 */
261 public void setStoragePath(String storage_path) {
262 storage_path_ = storage_path;
263 }
264
265 /**
266 * Get a UNIX timestamp of the file creation time
267 *
268 * @return A UNIX timestamp of the time that file was created
269 */
270 public long getCreationTimestamp() {
271 return creation_timestamp_;
272 }
273
274 /**
275 * Set a UNIX timestamp of the time the file was created
276 *
277 * @param creation_timestamp
278 * to set
279 */
280 public void setCreationTimestamp(long creation_timestamp) {
281 creation_timestamp_ = creation_timestamp;
282 }
283
284 /**
285 * Get a UNIX timestamp of the file modification time
286 *
287 * @return A UNIX timestamp of the modification time
288 */
289 public long getModificationTimestamp() {
290 return modified_timestamp_;
291 }
292
293 /**
294 * Set a UNIX timestamp of the time the time the file was modified.
295 *
296 * @param modification_timestamp
297 * to set
298 */
299 public void setModificationTimestamp(long modification_timestamp) {
300 modified_timestamp_ = modification_timestamp;
301 }
302
303 /**
304 * Returns the filename and "/" for the root directory
305 *
306 * @return The name of the file
307 */
308 public String getFileName() {
309 if (path_ != null) {
310 File f = new File(path_);
311 return f.getName().equals("") ? "/" : f.getName();
312 }
313 return null;
314 }
315
316 /**
317 * Can be used to get the Mimetype
318 *
319 * @return the Mimetype as a String
320 */
321 public String getMimetype() {
322 return mimetype_;
323 }
324
325 /**
326 * Instruct the file to save itself to the database
327 */
328 public void save() {
329 ContentValues cv = new ContentValues();
330 cv.put(ProviderTableMeta.FILE_MODIFIED, modified_timestamp_);
331 cv.put(ProviderTableMeta.FILE_CREATION, creation_timestamp_);
332 cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, length_);
333 cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, mimetype_);
334 cv.put(ProviderTableMeta.FILE_NAME, getFileName());
335 if (parent_id_ != 0)
336 cv.put(ProviderTableMeta.FILE_PARENT, parent_id_);
337 cv.put(ProviderTableMeta.FILE_PATH, path_);
338 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, storage_path_);
339 cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, account_.name);
340
341 if (fileExists()) {
342 if (providerClient_ != null) {
343 try {
344 providerClient_.update(ProviderTableMeta.CONTENT_URI, cv,
345 ProviderTableMeta._ID + "=?",
346 new String[] { String.valueOf(id_) });
347 } catch (RemoteException e) {
348 Log.e(TAG, e.getMessage());
349 return;
350 }
351 } else {
352 contentResolver_.update(ProviderTableMeta.CONTENT_URI, cv,
353 ProviderTableMeta._ID + "=?",
354 new String[] { String.valueOf(id_) });
355 }
356 } else {
357 Uri new_entry = null;
358 if (providerClient_ != null) {
359 try {
360 new_entry = providerClient_.insert(ProviderTableMeta.CONTENT_URI_FILE,
361 cv);
362 } catch (RemoteException e) {
363 Log.e(TAG, e.getMessage());
364 id_ = -1;
365 return;
366 }
367 } else {
368 new_entry = contentResolver_.insert(
369 ProviderTableMeta.CONTENT_URI_FILE, cv);
370 }
371 try {
372 String p = new_entry.getEncodedPath();
373 id_ = Integer.parseInt(p.substring(p.lastIndexOf('/') + 1));
374 } catch (NumberFormatException e) {
375 Log.e(TAG,
376 "Can't retrieve file id from uri: "
377 + new_entry.toString() + ", reason: "
378 + e.getMessage());
379 id_ = -1;
380 }
381 }
382 }
383
384 /**
385 * List the directory content
386 *
387 * @return The directory content or null, if the file is not a directory
388 */
389 public Vector<OCFile> getDirectoryContent() {
390 if (isDirectory() && id_ != -1) {
391 Vector<OCFile> ret = new Vector<OCFile>();
392
393 Uri req_uri = Uri.withAppendedPath(
394 ProviderTableMeta.CONTENT_URI_DIR, String.valueOf(id_));
395 Cursor c = null;
396 if (providerClient_ != null) {
397 try {
398 c = providerClient_.query(req_uri, null, null, null, null);
399 } catch (RemoteException e) {
400 Log.e(TAG, e.getMessage());
401 return ret;
402 }
403 } else {
404 c = contentResolver_.query(req_uri, null, null, null, null);
405 }
406
407 if (c.moveToFirst())
408 do {
409 OCFile child = new OCFile(providerClient_, account_);
410 child.setFileData(c);
411 ret.add(child);
412 } while (c.moveToNext());
413
414 c.close();
415 return ret;
416 }
417 return null;
418 }
419
420 /**
421 * Adds a file to this directory. If this file is not a directory, an
422 * exception gets thrown.
423 *
424 * @param file
425 * to add
426 * @throws IllegalStateException
427 * if you try to add a something and this is not a directory
428 */
429 public void addFile(OCFile file) throws IllegalStateException {
430 if (isDirectory()) {
431 file.parent_id_ = id_;
432 file.save();
433 return;
434 }
435 throw new IllegalStateException(
436 "This is not a directory where you can add stuff to!");
437 }
438
439 /**
440 * Used internally. Reset all file properties
441 */
442 private void resetData() {
443 id_ = -1;
444 path_ = null;
445 parent_id_ = 0;
446 storage_path_ = null;
447 mimetype_ = null;
448 length_ = 0;
449 creation_timestamp_ = 0;
450 modified_timestamp_ = 0;
451 }
452
453 /**
454 * Used internally. Set properties based on the information in a {@link android.database.Cursor}
455 * @param c the Cursor containing the information
456 */
457 private void setFileData(Cursor c) {
458 resetData();
459 if (c != null) {
460 id_ = c.getLong(c.getColumnIndex(ProviderTableMeta._ID));
461 path_ = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH));
462 parent_id_ = c.getLong(c
463 .getColumnIndex(ProviderTableMeta.FILE_PARENT));
464 storage_path_ = c.getString(c
465 .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
466 mimetype_ = c.getString(c
467 .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE));
468 length_ = c.getLong(c
469 .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));
470 creation_timestamp_ = c.getLong(c
471 .getColumnIndex(ProviderTableMeta.FILE_CREATION));
472 modified_timestamp_ = c.getLong(c
473 .getColumnIndex(ProviderTableMeta.FILE_MODIFIED));
474 }
475 }
476 }