b7ab2613969843f1d9afdca30c497969bccc13e8
[pub/Android/ownCloud.git] / src / eu / alefzero / webdav / ChunkFromFileChannelRequestEntity.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.webdav;
20
21 import java.io.IOException;
22 import java.io.OutputStream;
23 import java.nio.ByteBuffer;
24 import java.nio.channels.FileChannel;
25 import java.util.Collection;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.Set;
29
30 import org.apache.commons.httpclient.methods.RequestEntity;
31
32 import eu.alefzero.webdav.OnDatatransferProgressListener;
33
34 import android.util.Log;
35
36
37 /**
38 * A RequestEntity that represents a PIECE of a file.
39 *
40 * @author David A. Velasco
41 */
42 public class ChunkFromFileChannelRequestEntity implements RequestEntity {
43
44 private static final String TAG = ChunkFromFileChannelRequestEntity.class.getSimpleName();
45
46 //private final File mFile;
47 private final FileChannel mChannel;
48 private final String mContentType;
49 private final long mSize;
50 private long mOffset;
51 Set<OnDatatransferProgressListener> mListeners = new HashSet<OnDatatransferProgressListener>();
52 private ByteBuffer mBuffer = ByteBuffer.allocate(4096);
53
54 public ChunkFromFileChannelRequestEntity(final FileChannel channel, final String contentType, long size) {
55 super();
56 if (channel == null) {
57 throw new IllegalArgumentException("File may not be null");
58 }
59 if (size <= 0) {
60 throw new IllegalArgumentException("Size must be greater than zero");
61 }
62 mChannel = channel;
63 mContentType = contentType;
64 mSize = size;
65 mOffset = 0;
66 }
67
68 public void setOffset(long offset) {
69 mOffset = offset;
70 }
71
72 public long getContentLength() {
73 try {
74 return Math.min(mSize, mChannel.size() - mChannel.position());
75 } catch (IOException e) {
76 return mSize;
77 }
78 }
79
80 public String getContentType() {
81 return mContentType;
82 }
83
84 public boolean isRepeatable() {
85 return true;
86 }
87
88 public void addOnDatatransferProgressListener(OnDatatransferProgressListener listener) {
89 mListeners.add(listener);
90 }
91
92 public void addOnDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners) {
93 mListeners.addAll(listeners);
94 }
95
96 public void removeOnDatatransferProgressListener(OnDatatransferProgressListener listener) {
97 mListeners.remove(listener);
98 }
99
100
101 public void writeRequest(final OutputStream out) throws IOException {
102 int readCount = 0;
103 Iterator<OnDatatransferProgressListener> it = null;
104
105 try {
106 mChannel.position(mOffset);
107 while (mChannel.position() < mOffset + mSize && mChannel.position() < mChannel.size()) {
108 readCount = mChannel.read(mBuffer);
109 out.write(mBuffer.array(), 0, readCount);
110 mBuffer.clear();
111 it = mListeners.iterator();
112 while (it.hasNext()) {
113 it.next().onTransferProgress(readCount);
114 }
115 }
116
117 } catch (IOException io) {
118 Log.e(TAG, io.getMessage());
119 throw new RuntimeException("Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really", io);
120
121 }
122 }
123
124 }