1 /* ownCloud Android client application 
   2  *   Copyright (C) 2012  Bartek Przybylski 
   3  *   Copyright (C) 2012-2013 ownCloud Inc. 
   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. 
   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. 
  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/>. 
  19 package com
.owncloud
.android
.datamodel
; 
  23 import com
.owncloud
.android
.utils
.Log_OC
; 
  26 import android
.os
.Parcel
; 
  27 import android
.os
.Parcelable
; 
  28 import android
.webkit
.MimeTypeMap
; 
  30 public class OCFile 
implements Parcelable
, Comparable
<OCFile
> { 
  32     public static final Parcelable
.Creator
<OCFile
> CREATOR 
= new Parcelable
.Creator
<OCFile
>() { 
  34         public OCFile 
createFromParcel(Parcel source
) { 
  35             return new OCFile(source
); 
  39         public OCFile
[] newArray(int size
) { 
  40             return new OCFile
[size
]; 
  44     public static final String PATH_SEPARATOR 
= "/"; 
  45     public static final String ROOT_PATH 
= PATH_SEPARATOR
; 
  47     private static final String TAG 
= OCFile
.class.getSimpleName(); 
  50     private long mParentId
; 
  52     private long mCreationTimestamp
; 
  53     private long mModifiedTimestamp
; 
  54     private long mModifiedTimestampAtLastSyncForData
; 
  55     private String mRemotePath
; 
  56     private String mLocalPath
; 
  57     private String mMimeType
; 
  58     private boolean mNeedsUpdating
; 
  59     private long mLastSyncDateForProperties
; 
  60     private long mLastSyncDateForData
; 
  61     private boolean mKeepInSync
; 
  67      * Create new {@link OCFile} with given path. 
  69      * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'. 
  71      * @param path The remote path of the file. 
  73     public OCFile(String path
) { 
  75         mNeedsUpdating 
= false
; 
  76         if (path 
== null 
|| path
.length() <= 0 || !path
.startsWith(PATH_SEPARATOR
)) { 
  77             throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path
); 
  83      * Reconstruct from parcel 
  85      * @param source The source parcel 
  87     private OCFile(Parcel source
) { 
  88         mId 
= source
.readLong(); 
  89         mParentId 
= source
.readLong(); 
  90         mLength 
= source
.readLong(); 
  91         mCreationTimestamp 
= source
.readLong(); 
  92         mModifiedTimestamp 
= source
.readLong(); 
  93         mModifiedTimestampAtLastSyncForData 
= source
.readLong(); 
  94         mRemotePath 
= source
.readString(); 
  95         mLocalPath 
= source
.readString(); 
  96         mMimeType 
= source
.readString(); 
  97         mNeedsUpdating 
= source
.readInt() == 0; 
  98         mKeepInSync 
= source
.readInt() == 1; 
  99         mLastSyncDateForProperties 
= source
.readLong(); 
 100         mLastSyncDateForData 
= source
.readLong(); 
 101         mEtag 
= source
.readString(); 
 105     public void writeToParcel(Parcel dest
, int flags
) { 
 107         dest
.writeLong(mParentId
); 
 108         dest
.writeLong(mLength
); 
 109         dest
.writeLong(mCreationTimestamp
); 
 110         dest
.writeLong(mModifiedTimestamp
); 
 111         dest
.writeLong(mModifiedTimestampAtLastSyncForData
); 
 112         dest
.writeString(mRemotePath
); 
 113         dest
.writeString(mLocalPath
); 
 114         dest
.writeString(mMimeType
); 
 115         dest
.writeInt(mNeedsUpdating ? 
1 : 0); 
 116         dest
.writeInt(mKeepInSync ? 
1 : 0); 
 117         dest
.writeLong(mLastSyncDateForProperties
); 
 118         dest
.writeLong(mLastSyncDateForData
); 
 119         dest
.writeString(mEtag
); 
 123      * Gets the ID of the file 
 125      * @return the file ID 
 127     public long getFileId() { 
 132      * Returns the remote path of the file on ownCloud 
 134      * @return The remote path to the file 
 136     public String 
getRemotePath() { 
 141      * Can be used to check, whether or not this file exists in the database 
 144      * @return true, if the file exists in the database 
 146     public boolean fileExists() { 
 151      * Use this to find out if this file is a folder. 
 153      * @return true if it is a folder 
 155     public boolean isFolder() { 
 156         return mMimeType 
!= null 
&& mMimeType
.equals("DIR"); 
 160      * Use this to check if this file is available locally 
 162      * @return true if it is 
 164     public boolean isDown() { 
 165         if (mLocalPath 
!= null 
&& mLocalPath
.length() > 0) { 
 166             File file 
= new File(mLocalPath
); 
 167             return (file
.exists()); 
 173      * The path, where the file is stored locally 
 175      * @return The local path to the file 
 177     public String 
getStoragePath() { 
 182      * Can be used to set the path where the file is stored 
 184      * @param storage_path to set 
 186     public void setStoragePath(String storage_path
) { 
 187         mLocalPath 
= storage_path
; 
 191      * Get a UNIX timestamp of the file creation time 
 193      * @return A UNIX timestamp of the time that file was created 
 195     public long getCreationTimestamp() { 
 196         return mCreationTimestamp
; 
 200      * Set a UNIX timestamp of the time the file was created 
 202      * @param creation_timestamp to set 
 204     public void setCreationTimestamp(long creation_timestamp
) { 
 205         mCreationTimestamp 
= creation_timestamp
; 
 209      * Get a UNIX timestamp of the file modification time. 
 211      * @return  A UNIX timestamp of the modification time, corresponding to the value returned by the server 
 212      *          in the last synchronization of the properties of this file.  
 214     public long getModificationTimestamp() { 
 215         return mModifiedTimestamp
; 
 219      * Set a UNIX timestamp of the time the time the file was modified. 
 221      * To update with the value returned by the server in every synchronization of the properties  
 224      * @param modification_timestamp to set 
 226     public void setModificationTimestamp(long modification_timestamp
) { 
 227         mModifiedTimestamp 
= modification_timestamp
; 
 232      * Get a UNIX timestamp of the file modification time. 
 234      * @return  A UNIX timestamp of the modification time, corresponding to the value returned by the server 
 235      *          in the last synchronization of THE CONTENTS of this file.  
 237     public long getModificationTimestampAtLastSyncForData() { 
 238         return mModifiedTimestampAtLastSyncForData
; 
 242      * Set a UNIX timestamp of the time the time the file was modified. 
 244      * To update with the value returned by the server in every synchronization of THE CONTENTS  
 247      * @param modification_timestamp to set 
 249     public void setModificationTimestampAtLastSyncForData(long modificationTimestamp
) { 
 250         mModifiedTimestampAtLastSyncForData 
= modificationTimestamp
; 
 256      * Returns the filename and "/" for the root directory 
 258      * @return The name of the file 
 260     public String 
getFileName() { 
 261         File f 
= new File(getRemotePath()); 
 262         return f
.getName().length() == 0 ? ROOT_PATH 
: f
.getName(); 
 266      * Sets the name of the file 
 268      * Does nothing if the new name is null, empty or includes "/" ; or if the file is the root directory  
 270     public void setFileName(String name
) { 
 271         Log_OC
.d(TAG
, "OCFile name changin from " + mRemotePath
); 
 272         if (name 
!= null 
&& name
.length() > 0 && !name
.contains(PATH_SEPARATOR
) && !mRemotePath
.equals(ROOT_PATH
)) { 
 273             String parent 
= (new File(getRemotePath())).getParent(); 
 274             parent 
= (parent
.endsWith(PATH_SEPARATOR
)) ? parent 
: parent 
+ PATH_SEPARATOR
; 
 275             mRemotePath 
=  parent 
+ name
; 
 277                 mRemotePath 
+= PATH_SEPARATOR
; 
 279             Log_OC
.d(TAG
, "OCFile name changed to " + mRemotePath
); 
 284      * Can be used to get the Mimetype 
 286      * @return the Mimetype as a String 
 288     public String 
getMimetype() { 
 293      * Adds a file to this directory. If this file is not a directory, an 
 294      * exception gets thrown. 
 297      * @throws IllegalStateException if you try to add a something and this is 
 300     public void addFile(OCFile file
) throws IllegalStateException 
{ 
 302             file
.mParentId 
= mId
; 
 303             mNeedsUpdating 
= true
; 
 306         throw new IllegalStateException( 
 307                 "This is not a directory where you can add stuff to!"); 
 311      * Used internally. Reset all file properties 
 313     private void resetData() { 
 320         mCreationTimestamp 
= 0; 
 321         mModifiedTimestamp 
= 0; 
 322         mModifiedTimestampAtLastSyncForData 
= 0; 
 323         mLastSyncDateForProperties 
= 0; 
 324         mLastSyncDateForData 
= 0; 
 326         mNeedsUpdating 
= false
; 
 331      * Sets the ID of the file 
 333      * @param file_id to set 
 335     public void setFileId(long file_id
) { 
 340      * Sets the Mime-Type of the 
 342      * @param mimetype to set 
 344     public void setMimetype(String mimetype
) { 
 345         mMimeType 
= mimetype
; 
 349      * Sets the ID of the parent folder 
 351      * @param parent_id to set 
 353     public void setParentId(long parent_id
) { 
 354         mParentId 
= parent_id
; 
 358      * Sets the file size in bytes 
 360      * @param file_len to set 
 362     public void setFileLength(long file_len
) { 
 367      * Returns the size of the file in bytes 
 369      * @return The filesize in bytes 
 371     public long getFileLength() { 
 376      * Returns the ID of the parent Folder 
 380     public long getParentId() { 
 385      * Check, if this file needs updating 
 389     public boolean needsUpdatingWhileSaving() { 
 390         return mNeedsUpdating
; 
 393     public long getLastSyncDateForProperties() { 
 394         return mLastSyncDateForProperties
; 
 397     public void setLastSyncDateForProperties(long lastSyncDate
) { 
 398         mLastSyncDateForProperties 
= lastSyncDate
; 
 401     public long getLastSyncDateForData() { 
 402         return mLastSyncDateForData
; 
 405     public void setLastSyncDateForData(long lastSyncDate
) { 
 406         mLastSyncDateForData 
= lastSyncDate
; 
 409     public void setKeepInSync(boolean keepInSync
) { 
 410         mKeepInSync 
= keepInSync
; 
 413     public boolean keepInSync() { 
 418     public int describeContents() { 
 419         return this.hashCode(); 
 423     public int compareTo(OCFile another
) { 
 424         if (isFolder() && another
.isFolder()) { 
 425             return getRemotePath().toLowerCase().compareTo(another
.getRemotePath().toLowerCase()); 
 426         } else if (isFolder()) { 
 428         } else if (another
.isFolder()) { 
 431         return getRemotePath().toLowerCase().compareTo(another
.getRemotePath().toLowerCase()); 
 435     public boolean equals(Object o
) { 
 436         if(o 
instanceof OCFile
){ 
 437             OCFile that 
= (OCFile
) o
; 
 439                 return this.mId 
== that
.mId
; 
 447     public String 
toString() { 
 448         String asString 
= "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, parentId=%s, keepInSinc=%s etag=%s]"; 
 449         asString 
= String
.format(asString
, Long
.valueOf(mId
), getFileName(), mMimeType
, isDown(), mLocalPath
, mRemotePath
, Long
.valueOf(mParentId
), Boolean
.valueOf(mKeepInSync
), mEtag
); 
 453     public String 
getEtag() { 
 457     public void setEtag(String etag
) { 
 461     public long getLocalModificationTimestamp() { 
 462         if (mLocalPath 
!= null 
&& mLocalPath
.length() > 0) { 
 463             File f 
= new File(mLocalPath
); 
 464             return f
.lastModified(); 
 469     /** @return  'True' if the file contains audio */ 
 470     public boolean isAudio() { 
 471         return (mMimeType 
!= null 
&& mMimeType
.startsWith("audio/")); 
 474     /** @return  'True' if the file contains video */ 
 475     public boolean isVideo() { 
 476         return (mMimeType 
!= null 
&& mMimeType
.startsWith("video/")); 
 479     /** @return  'True' if the file contains an image */ 
 480     public boolean isImage() { 
 481         return ((mMimeType 
!= null 
&& mMimeType
.startsWith("image/")) || 
 482                  getMimeTypeFromName().startsWith("image/")); 
 485     public String 
getMimeTypeFromName() { 
 486         String extension 
= ""; 
 487         int pos 
= mRemotePath
.lastIndexOf('.'); 
 489             extension 
= mRemotePath
.substring(pos 
+ 1); 
 491         String result 
= MimeTypeMap
.getSingleton().getMimeTypeFromExtension(extension
.toLowerCase()); 
 492         return (result 
!= null
) ? result 
: "";