Remove share_group_indicator string
[pub/Android/ownCloud.git] / src / com / owncloud / android / datamodel / OCFile.java
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
21 package com.owncloud.android.datamodel;
22
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.webkit.MimeTypeMap;
26
27 import com.owncloud.android.lib.common.utils.Log_OC;
28
29 import java.io.File;
30
31 import third_parties.daveKoeller.AlphanumComparator;
32 public class OCFile implements Parcelable, Comparable<OCFile> {
33
34 public static final Parcelable.Creator<OCFile> CREATOR = new Parcelable.Creator<OCFile>() {
35 @Override
36 public OCFile createFromParcel(Parcel source) {
37 return new OCFile(source);
38 }
39
40 @Override
41 public OCFile[] newArray(int size) {
42 return new OCFile[size];
43 }
44 };
45
46 private final static String PERMISSION_SHARED_WITH_ME = "S"; // TODO move to better location
47
48 public static final String PATH_SEPARATOR = "/";
49 public static final String ROOT_PATH = PATH_SEPARATOR;
50
51 private static final String TAG = OCFile.class.getSimpleName();
52
53 private long mId;
54 private long mParentId;
55 private long mLength;
56 private long mCreationTimestamp;
57 private long mModifiedTimestamp;
58 private long mModifiedTimestampAtLastSyncForData;
59 private String mRemotePath;
60 private String mLocalPath;
61 private String mMimeType;
62 private boolean mNeedsUpdating;
63 private long mLastSyncDateForProperties;
64 private long mLastSyncDateForData;
65 private boolean mFavorite;
66
67 private String mEtag;
68
69 private boolean mShareByLink;
70 private String mPublicLink;
71
72 private String mPermissions;
73 private String mRemoteId;
74
75 private boolean mNeedsUpdateThumbnail;
76
77 private boolean mIsDownloading;
78
79 private String mEtagInConflict; // Save file etag in the server, when there is a conflict. No conflict = null
80
81 private boolean mShareWithUser;
82
83
84 /**
85 * Create new {@link OCFile} with given path.
86 * <p/>
87 * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
88 *
89 * @param path The remote path of the file.
90 */
91 public OCFile(String path) {
92 resetData();
93 mNeedsUpdating = false;
94 if (path == null || path.length() <= 0 || !path.startsWith(PATH_SEPARATOR)) {
95 throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
96 }
97 mRemotePath = path;
98 }
99
100 /**
101 * Reconstruct from parcel
102 *
103 * @param source The source parcel
104 */
105 private OCFile(Parcel source) {
106 mId = source.readLong();
107 mParentId = source.readLong();
108 mLength = source.readLong();
109 mCreationTimestamp = source.readLong();
110 mModifiedTimestamp = source.readLong();
111 mModifiedTimestampAtLastSyncForData = source.readLong();
112 mRemotePath = source.readString();
113 mLocalPath = source.readString();
114 mMimeType = source.readString();
115 mNeedsUpdating = source.readInt() == 0;
116 mFavorite = source.readInt() == 1;
117 mLastSyncDateForProperties = source.readLong();
118 mLastSyncDateForData = source.readLong();
119 mEtag = source.readString();
120 mShareByLink = source.readInt() == 1;
121 mPublicLink = source.readString();
122 mPermissions = source.readString();
123 mRemoteId = source.readString();
124 mNeedsUpdateThumbnail = source.readInt() == 1;
125 mIsDownloading = source.readInt() == 1;
126 mEtagInConflict = source.readString();
127 mShareWithUser = source.readInt() == 1;
128
129 }
130
131 @Override
132 public void writeToParcel(Parcel dest, int flags) {
133 dest.writeLong(mId);
134 dest.writeLong(mParentId);
135 dest.writeLong(mLength);
136 dest.writeLong(mCreationTimestamp);
137 dest.writeLong(mModifiedTimestamp);
138 dest.writeLong(mModifiedTimestampAtLastSyncForData);
139 dest.writeString(mRemotePath);
140 dest.writeString(mLocalPath);
141 dest.writeString(mMimeType);
142 dest.writeInt(mNeedsUpdating ? 1 : 0);
143 dest.writeInt(mFavorite ? 1 : 0);
144 dest.writeLong(mLastSyncDateForProperties);
145 dest.writeLong(mLastSyncDateForData);
146 dest.writeString(mEtag);
147 dest.writeInt(mShareByLink ? 1 : 0);
148 dest.writeString(mPublicLink);
149 dest.writeString(mPermissions);
150 dest.writeString(mRemoteId);
151 dest.writeInt(mNeedsUpdateThumbnail ? 1 : 0);
152 dest.writeInt(mIsDownloading ? 1 : 0);
153 dest.writeString(mEtagInConflict);
154 dest.writeInt(mShareWithUser ? 1 : 0);
155 }
156
157 /**
158 * Gets the ID of the file
159 *
160 * @return the file ID
161 */
162 public long getFileId() {
163 return mId;
164 }
165
166 /**
167 * Returns the remote path of the file on ownCloud
168 *
169 * @return The remote path to the file
170 */
171 public String getRemotePath() {
172 return mRemotePath;
173 }
174
175 /**
176 * Can be used to check, whether or not this file exists in the database
177 * already
178 *
179 * @return true, if the file exists in the database
180 */
181 public boolean fileExists() {
182 return mId != -1;
183 }
184
185 /**
186 * Use this to find out if this file is a folder.
187 *
188 * @return true if it is a folder
189 */
190 public boolean isFolder() {
191 return mMimeType != null && mMimeType.equals("DIR");
192 }
193
194 /**
195 * Use this to check if this file is available locally
196 *
197 * @return true if it is
198 */
199 public boolean isDown() {
200 if (mLocalPath != null && mLocalPath.length() > 0) {
201 File file = new File(mLocalPath);
202 return (file.exists());
203 }
204 return false;
205 }
206
207 /**
208 * The path, where the file is stored locally
209 *
210 * @return The local path to the file
211 */
212 public String getStoragePath() {
213 return mLocalPath;
214 }
215
216 /**
217 * Can be used to set the path where the file is stored
218 *
219 * @param storage_path to set
220 */
221 public void setStoragePath(String storage_path) {
222 mLocalPath = storage_path;
223 }
224
225 /**
226 * Get a UNIX timestamp of the file creation time
227 *
228 * @return A UNIX timestamp of the time that file was created
229 */
230 public long getCreationTimestamp() {
231 return mCreationTimestamp;
232 }
233
234 /**
235 * Set a UNIX timestamp of the time the file was created
236 *
237 * @param creation_timestamp to set
238 */
239 public void setCreationTimestamp(long creation_timestamp) {
240 mCreationTimestamp = creation_timestamp;
241 }
242
243 /**
244 * Get a UNIX timestamp of the file modification time.
245 *
246 * @return A UNIX timestamp of the modification time, corresponding to the value returned by the server
247 * in the last synchronization of the properties of this file.
248 */
249 public long getModificationTimestamp() {
250 return mModifiedTimestamp;
251 }
252
253 /**
254 * Set a UNIX timestamp of the time the time the file was modified.
255 * <p/>
256 * To update with the value returned by the server in every synchronization of the properties
257 * of this file.
258 *
259 * @param modification_timestamp to set
260 */
261 public void setModificationTimestamp(long modification_timestamp) {
262 mModifiedTimestamp = modification_timestamp;
263 }
264
265
266 /**
267 * Get a UNIX timestamp of the file modification time.
268 *
269 * @return A UNIX timestamp of the modification time, corresponding to the value returned by the server
270 * in the last synchronization of THE CONTENTS of this file.
271 */
272 public long getModificationTimestampAtLastSyncForData() {
273 return mModifiedTimestampAtLastSyncForData;
274 }
275
276 /**
277 * Set a UNIX timestamp of the time the time the file was modified.
278 * <p/>
279 * To update with the value returned by the server in every synchronization of THE CONTENTS
280 * of this file.
281 *
282 * @param modificationTimestamp to set
283 */
284 public void setModificationTimestampAtLastSyncForData(long modificationTimestamp) {
285 mModifiedTimestampAtLastSyncForData = modificationTimestamp;
286 }
287
288
289 /**
290 * Returns the filename and "/" for the root directory
291 *
292 * @return The name of the file
293 */
294 public String getFileName() {
295 File f = new File(getRemotePath());
296 return f.getName().length() == 0 ? ROOT_PATH : f.getName();
297 }
298
299 /**
300 * Sets the name of the file
301 * <p/>
302 * Does nothing if the new name is null, empty or includes "/" ; or if the file is the root
303 * directory
304 */
305 public void setFileName(String name) {
306 Log_OC.d(TAG, "OCFile name changin from " + mRemotePath);
307 if (name != null && name.length() > 0 && !name.contains(PATH_SEPARATOR) &&
308 !mRemotePath.equals(ROOT_PATH)) {
309 String parent = (new File(getRemotePath())).getParent();
310 parent = (parent.endsWith(PATH_SEPARATOR)) ? parent : parent + PATH_SEPARATOR;
311 mRemotePath = parent + name;
312 if (isFolder()) {
313 mRemotePath += PATH_SEPARATOR;
314 }
315 Log_OC.d(TAG, "OCFile name changed to " + mRemotePath);
316 }
317 }
318
319 /**
320 * Can be used to get the Mimetype
321 *
322 * @return the Mimetype as a String
323 */
324 public String getMimetype() {
325 return mMimeType;
326 }
327
328 /**
329 * Used internally. Reset all file properties
330 */
331 private void resetData() {
332 mId = -1;
333 mRemotePath = null;
334 mParentId = 0;
335 mLocalPath = null;
336 mMimeType = null;
337 mLength = 0;
338 mCreationTimestamp = 0;
339 mModifiedTimestamp = 0;
340 mModifiedTimestampAtLastSyncForData = 0;
341 mLastSyncDateForProperties = 0;
342 mLastSyncDateForData = 0;
343 mFavorite = false;
344 mNeedsUpdating = false;
345 mEtag = null;
346 mShareByLink = false;
347 mPublicLink = null;
348 mPermissions = null;
349 mRemoteId = null;
350 mNeedsUpdateThumbnail = false;
351 mIsDownloading = false;
352 mEtagInConflict = null;
353 mShareWithUser = false;
354 }
355
356 /**
357 * Sets the ID of the file
358 *
359 * @param file_id to set
360 */
361 public void setFileId(long file_id) {
362 mId = file_id;
363 }
364
365 /**
366 * Sets the Mime-Type of the
367 *
368 * @param mimetype to set
369 */
370 public void setMimetype(String mimetype) {
371 mMimeType = mimetype;
372 }
373
374 /**
375 * Sets the ID of the parent folder
376 *
377 * @param parent_id to set
378 */
379 public void setParentId(long parent_id) {
380 mParentId = parent_id;
381 }
382
383 /**
384 * Sets the file size in bytes
385 *
386 * @param file_len to set
387 */
388 public void setFileLength(long file_len) {
389 mLength = file_len;
390 }
391
392 /**
393 * Returns the size of the file in bytes
394 *
395 * @return The filesize in bytes
396 */
397 public long getFileLength() {
398 return mLength;
399 }
400
401 /**
402 * Returns the ID of the parent Folder
403 *
404 * @return The ID
405 */
406 public long getParentId() {
407 return mParentId;
408 }
409
410 /**
411 * Check, if this file needs updating
412 *
413 * @return
414 */
415 public boolean needsUpdatingWhileSaving() {
416 return mNeedsUpdating;
417 }
418
419 public boolean needsUpdateThumbnail() {
420 return mNeedsUpdateThumbnail;
421 }
422
423 public void setNeedsUpdateThumbnail(boolean needsUpdateThumbnail) {
424 this.mNeedsUpdateThumbnail = needsUpdateThumbnail;
425 }
426
427 public long getLastSyncDateForProperties() {
428 return mLastSyncDateForProperties;
429 }
430
431 public void setLastSyncDateForProperties(long lastSyncDate) {
432 mLastSyncDateForProperties = lastSyncDate;
433 }
434
435 public long getLastSyncDateForData() {
436 return mLastSyncDateForData;
437 }
438
439 public void setLastSyncDateForData(long lastSyncDate) {
440 mLastSyncDateForData = lastSyncDate;
441 }
442
443 public void setFavorite(boolean favorite) {
444 mFavorite = favorite;
445 }
446
447 public boolean isFavorite() {
448 return mFavorite;
449 }
450
451 @Override
452 public int describeContents() {
453 return super.hashCode();
454 }
455
456 @Override
457 public int compareTo(OCFile another) {
458 if (isFolder() && another.isFolder()) {
459 return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
460 } else if (isFolder()) {
461 return -1;
462 } else if (another.isFolder()) {
463 return 1;
464 }
465 return new AlphanumComparator().compare(this, another);
466 }
467
468 @Override
469 public boolean equals(Object o) {
470 if (o instanceof OCFile) {
471 OCFile that = (OCFile) o;
472 if (that != null) {
473 return this.mId == that.mId;
474 }
475 }
476
477 return false;
478 }
479
480 @Override
481 public String toString() {
482 String asString = "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, " +
483 "parentId=%s, favorite=%s etag=%s]";
484 asString = String.format(asString, Long.valueOf(mId), getFileName(), mMimeType, isDown(),
485 mLocalPath, mRemotePath, Long.valueOf(mParentId), Boolean.valueOf(mFavorite),
486 mEtag);
487 return asString;
488 }
489
490 public String getEtag() {
491 return mEtag;
492 }
493
494 public void setEtag(String etag) {
495 this.mEtag = (etag != null ? etag : "");
496 }
497
498
499 public boolean isSharedViaLink() {
500 return mShareByLink;
501 }
502
503 public void setShareViaLink(boolean shareByLink) {
504 this.mShareByLink = shareByLink;
505 }
506
507 public String getPublicLink() {
508 return mPublicLink;
509 }
510
511 public void setPublicLink(String publicLink) {
512 this.mPublicLink = publicLink;
513 }
514
515 public long getLocalModificationTimestamp() {
516 if (mLocalPath != null && mLocalPath.length() > 0) {
517 File f = new File(mLocalPath);
518 return f.lastModified();
519 }
520 return 0;
521 }
522
523 /**
524 * @return 'True' if the file contains audio
525 */
526 public boolean isAudio() {
527 return (mMimeType != null && mMimeType.startsWith("audio/"));
528 }
529
530 /**
531 * @return 'True' if the file contains video
532 */
533 public boolean isVideo() {
534 return (mMimeType != null && mMimeType.startsWith("video/"));
535 }
536
537 /**
538 * @return 'True' if the file contains an image
539 */
540 public boolean isImage() {
541 return ((mMimeType != null && mMimeType.startsWith("image/")) ||
542 getMimeTypeFromName().startsWith("image/"));
543 }
544
545 /**
546 * @return 'True' if the file is simple text (e.g. not application-dependent, like .doc or .docx)
547 */
548 public boolean isText() {
549 return ((mMimeType != null && mMimeType.startsWith("text/")) ||
550 getMimeTypeFromName().startsWith("text/"));
551 }
552
553 public String getMimeTypeFromName() {
554 String extension = "";
555 int pos = mRemotePath.lastIndexOf('.');
556 if (pos >= 0) {
557 extension = mRemotePath.substring(pos + 1);
558 }
559 String result = MimeTypeMap.getSingleton().
560 getMimeTypeFromExtension(extension.toLowerCase());
561 return (result != null) ? result : "";
562 }
563
564 /**
565 * @return 'True' if the file is hidden
566 */
567 public boolean isHidden() {
568 return getFileName().startsWith(".");
569 }
570
571 public String getPermissions() {
572 return mPermissions;
573 }
574
575 public void setPermissions(String permissions) {
576 this.mPermissions = permissions;
577 }
578
579 public String getRemoteId() {
580 return mRemoteId;
581 }
582
583 public void setRemoteId(String remoteId) {
584 this.mRemoteId = remoteId;
585 }
586
587 public boolean isDownloading() {
588 return mIsDownloading;
589 }
590
591 public void setDownloading(boolean isDownloading) {
592 this.mIsDownloading = isDownloading;
593 }
594
595 public String getEtagInConflict() {
596 return mEtagInConflict;
597 }
598
599 public void setEtagInConflict(String etagInConflict) {
600 mEtagInConflict = etagInConflict;
601 }
602
603 public boolean isSharedViaUsers() {
604 return mShareWithUser;
605 }
606
607 public void setShareViaUsers(boolean shareWithUser) {
608 this.mShareWithUser = shareWithUser;
609 }
610
611 public boolean isSharedWithMe() {
612 String permissions = getPermissions();
613 return (permissions != null && permissions.contains(PERMISSION_SHARED_WITH_ME));
614 }
615 }