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 eu
.alefzero
.webdav
; 
  22 import java
.io
.IOException
; 
  23 import java
.io
.OutputStream
; 
  24 import java
.io
.RandomAccessFile
; 
  25 import java
.nio
.ByteBuffer
; 
  26 import java
.nio
.channels
.FileChannel
; 
  27 import java
.util
.Collection
; 
  28 import java
.util
.HashSet
; 
  29 import java
.util
.Iterator
; 
  32 import org
.apache
.commons
.httpclient
.methods
.RequestEntity
; 
  34 import com
.owncloud
.android
.Log_OC
; 
  35 import com
.owncloud
.android
.network
.ProgressiveDataTransferer
; 
  38 import eu
.alefzero
.webdav
.OnDatatransferProgressListener
; 
  42  * A RequestEntity that represents a File. 
  45 public class FileRequestEntity 
implements RequestEntity
, ProgressiveDataTransferer 
{ 
  48     final String mContentType
; 
  49     Set
<OnDatatransferProgressListener
> mDataTransferListeners 
= new HashSet
<OnDatatransferProgressListener
>(); 
  51     public FileRequestEntity(final File file
, final String contentType
) { 
  54         this.mContentType 
= contentType
; 
  56             throw new IllegalArgumentException("File may not be null"); 
  61     public long getContentLength() { 
  62         return mFile
.length(); 
  66     public String 
getContentType() { 
  71     public boolean isRepeatable() { 
  76     public void addDatatransferProgressListener(OnDatatransferProgressListener listener
) { 
  77         synchronized (mDataTransferListeners
) { 
  78             mDataTransferListeners
.add(listener
); 
  83     public void addDatatransferProgressListeners(Collection
<OnDatatransferProgressListener
> listeners
) { 
  84         synchronized (mDataTransferListeners
) { 
  85             mDataTransferListeners
.addAll(listeners
); 
  90     public void removeDatatransferProgressListener(OnDatatransferProgressListener listener
) { 
  91         synchronized (mDataTransferListeners
) { 
  92             mDataTransferListeners
.remove(listener
); 
  98     public void writeRequest(final OutputStream out
) throws IOException 
{ 
  99         //byte[] tmp = new byte[4096]; 
 100         ByteBuffer tmp 
= ByteBuffer
.allocate(4096); 
 103         // TODO(bprzybylski): each mem allocation can throw OutOfMemoryError we need to handle it 
 104         //                    globally in some fashionable manner 
 105         RandomAccessFile raf 
= new RandomAccessFile(mFile
, "r"); 
 106         FileChannel channel 
= raf
.getChannel(); 
 107         Iterator
<OnDatatransferProgressListener
> it 
= null
; 
 108         long transferred 
= 0; 
 109         long size 
= mFile
.length(); 
 110         if (size 
== 0) size 
= -1; 
 112             while ((readResult 
= channel
.read(tmp
)) >= 0) { 
 113                 out
.write(tmp
.array(), 0, readResult
); 
 115                 transferred 
+= readResult
; 
 116                 synchronized (mDataTransferListeners
) { 
 117                     it 
= mDataTransferListeners
.iterator(); 
 118                     while (it
.hasNext()) { 
 119                         it
.next().onTransferProgress(readResult
, transferred
, size
, mFile
.getName()); 
 124         } catch (IOException io
) { 
 125             Log_OC
.e("FileRequestException", io
.getMessage()); 
 126             throw new RuntimeException("Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really", io
);