9fde7c0f89d58a5dcb1c8169b578d7a0700017bc
[pub/Android/ownCloud.git] / oc_framework / src / com / owncloud / android / lib / operations / remote / ChunkedUploadRemoteFileOperation.java
1 /* ownCloud Android Library is available under MIT license
2 * Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
3 * Copyright (C) 2012 Bartek Przybylski
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 */
25
26 package com.owncloud.android.lib.operations.remote;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.RandomAccessFile;
31 import java.nio.channels.FileChannel;
32 import java.util.Random;
33
34 import org.apache.commons.httpclient.HttpException;
35 import org.apache.commons.httpclient.methods.PutMethod;
36
37 import com.owncloud.android.lib.network.ChunkFromFileChannelRequestEntity;
38 import com.owncloud.android.lib.network.OwnCloudClient;
39 import com.owncloud.android.lib.network.ProgressiveDataTransferer;
40 import com.owncloud.android.lib.network.webdav.WebdavUtils;
41
42
43 import android.util.Log;
44
45
46 public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation {
47
48 public static final long CHUNK_SIZE = 1024000;
49 private static final String OC_CHUNKED_HEADER = "OC-Chunked";
50 private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName();
51
52 public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) {
53 super(storagePath, remotePath, mimeType);
54 }
55
56 @Override
57 protected int uploadFile(OwnCloudClient client) throws HttpException, IOException {
58 int status = -1;
59
60 FileChannel channel = null;
61 RandomAccessFile raf = null;
62 try {
63 File file = new File(mStoragePath);
64 raf = new RandomAccessFile(file, "r");
65 channel = raf.getChannel();
66 mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file);
67 //((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners());
68 synchronized (mDataTransferListeners) {
69 ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners);
70 }
71
72 long offset = 0;
73 String uriPrefix = client.getBaseUri() + WebdavUtils.encodePath(mRemotePath) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ;
74 long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE);
75 for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) {
76 if (mPutMethod != null) {
77 mPutMethod.releaseConnection(); // let the connection available for other methods
78 }
79 mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex);
80 mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER);
81 ((ChunkFromFileChannelRequestEntity)mEntity).setOffset(offset);
82 mPutMethod.setRequestEntity(mEntity);
83 status = client.executeMethod(mPutMethod);
84 client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
85 Log.d(TAG, "Upload of " + mStoragePath + " to " + mRemotePath + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status);
86 if (!isSuccess(status))
87 break;
88 }
89
90 } finally {
91 if (channel != null)
92 channel.close();
93 if (raf != null)
94 raf.close();
95 if (mPutMethod != null)
96 mPutMethod.releaseConnection(); // let the connection available for other methods
97 }
98 return status;
99 }
100
101 }