OC-2388: Move ChunkedUploadFileOperation to the framework. UploadFileOperation select operation with or without chunks

This commit is contained in:
masensio 2013-12-16 10:46:29 +01:00
parent dc1ea137a2
commit e76d4b00ef
5 changed files with 50 additions and 46 deletions

View file

@ -16,7 +16,7 @@
* *
*/ */
package com.owncloud.android.operations; package com.owncloud.android.oc_framework.operations.remote;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -27,33 +27,23 @@ import java.util.Random;
import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.PutMethod;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.oc_framework.network.ProgressiveDataTransferer; import com.owncloud.android.oc_framework.network.ProgressiveDataTransferer;
import com.owncloud.android.oc_framework.network.webdav.ChunkFromFileChannelRequestEntity; import com.owncloud.android.oc_framework.network.webdav.ChunkFromFileChannelRequestEntity;
import com.owncloud.android.oc_framework.network.webdav.OnDatatransferProgressListener;
import com.owncloud.android.oc_framework.network.webdav.WebdavClient; import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
import com.owncloud.android.oc_framework.network.webdav.WebdavUtils; import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
import com.owncloud.android.utils.Log_OC;
import android.accounts.Account; import android.util.Log;
import android.content.Context;
public class ChunkedUploadFileOperation extends UploadFileOperation { public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation {
private static final long CHUNK_SIZE = 1024000; private static final long CHUNK_SIZE = 1024000;
private static final String OC_CHUNKED_HEADER = "OC-Chunked"; private static final String OC_CHUNKED_HEADER = "OC-Chunked";
private static final String TAG = ChunkedUploadFileOperation.class.getSimpleName(); private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName();
public ChunkedUploadFileOperation( Account account, public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) {
OCFile file, super(storagePath, remotePath, mimeType);
boolean isInstant,
boolean forceOverwrite,
int localBehaviour, Context context,
OnDatatransferProgressListener listener) {
super(account, file, isInstant, forceOverwrite, localBehaviour, context, listener);
} }
@Override @Override
@ -63,13 +53,17 @@ public class ChunkedUploadFileOperation extends UploadFileOperation {
FileChannel channel = null; FileChannel channel = null;
RandomAccessFile raf = null; RandomAccessFile raf = null;
try { try {
File file = new File(getStoragePath()); File file = new File(mStoragePath);
raf = new RandomAccessFile(file, "r"); raf = new RandomAccessFile(file, "r");
channel = raf.getChannel(); channel = raf.getChannel();
mEntity = new ChunkFromFileChannelRequestEntity(channel, getMimeType(), CHUNK_SIZE, file); mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file);
((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners()); //((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners());
synchronized (mDataTransferListeners) {
((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners);
}
long offset = 0; long offset = 0;
String uriPrefix = client.getBaseUri() + WebdavUtils.encodePath(getRemotePath()) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ; String uriPrefix = client.getBaseUri() + WebdavUtils.encodePath(mRemotePath) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ;
long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE); long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE);
for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) { for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) {
if (mPutMethod != null) { if (mPutMethod != null) {
@ -81,7 +75,7 @@ public class ChunkedUploadFileOperation extends UploadFileOperation {
mPutMethod.setRequestEntity(mEntity); mPutMethod.setRequestEntity(mEntity);
status = client.executeMethod(mPutMethod); status = client.executeMethod(mPutMethod);
client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
Log_OC.d(TAG, "Upload of " + getStoragePath() + " to " + getRemotePath() + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status); Log.d(TAG, "Upload of " + mStoragePath + " to " + mRemotePath + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status);
if (!isSuccess(status)) if (!isSuccess(status))
break; break;
} }

View file

@ -47,12 +47,13 @@ import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
public class UploadRemoteFileOperation extends RemoteOperation { public class UploadRemoteFileOperation extends RemoteOperation {
private String mStoragePath; protected String mStoragePath;
private String mRemotePath; protected String mRemotePath;
private String mMimeType; protected String mMimeType;
PutMethod mPutMethod = null; protected PutMethod mPutMethod = null;
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>(); protected Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
protected RequestEntity mEntity = null; protected RequestEntity mEntity = null;

View file

@ -38,7 +38,6 @@ import com.owncloud.android.authentication.AuthenticatorActivity;
import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.db.DbHandler; import com.owncloud.android.db.DbHandler;
import com.owncloud.android.operations.ChunkedUploadFileOperation;
import com.owncloud.android.operations.CreateFolderOperation; import com.owncloud.android.operations.CreateFolderOperation;
import com.owncloud.android.oc_framework.operations.RemoteOperation; import com.owncloud.android.oc_framework.operations.RemoteOperation;
import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
@ -251,7 +250,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i], ((mimeTypes != null) ? mimeTypes[i] files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i], ((mimeTypes != null) ? mimeTypes[i]
: (String) null), storageManager); : (String) null), storageManager);
if (files[i] == null) { if (files[i] == null) {
// TODO @andomaex add failure Notiification // TODO @andomaex add failure Notification
return Service.START_NOT_STICKY; return Service.START_NOT_STICKY;
} }
} }
@ -265,13 +264,15 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
try { try {
for (int i = 0; i < files.length; i++) { for (int i = 0; i < files.length; i++) {
uploadKey = buildRemoteName(account, files[i].getRemotePath()); uploadKey = buildRemoteName(account, files[i].getRemotePath());
if (chunked) { newUpload = new UploadFileOperation(account, files[i], chunked, isInstant, forceOverwrite, localAction,
newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite, getApplicationContext());
localAction, getApplicationContext(), this); // if (chunked) {
} else { // newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite,
newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction, // localAction, getApplicationContext());
getApplicationContext(), this); // } else {
} // newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction,
// getApplicationContext());
// }
if (isInstant) { if (isInstant) {
newUpload.setRemoteFolderToBeCreated(); newUpload.setRemoteFolderToBeCreated();
} }

View file

@ -24,6 +24,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -42,6 +43,7 @@ import com.owncloud.android.oc_framework.operations.OperationCancelledException;
import com.owncloud.android.oc_framework.operations.RemoteOperation; import com.owncloud.android.oc_framework.operations.RemoteOperation;
import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.oc_framework.operations.remote.ChunkedUploadRemoteFileOperation;
import com.owncloud.android.oc_framework.operations.remote.ExistenceCheckRemoteOperation; import com.owncloud.android.oc_framework.operations.remote.ExistenceCheckRemoteOperation;
import com.owncloud.android.oc_framework.operations.remote.UploadRemoteFileOperation; import com.owncloud.android.oc_framework.operations.remote.UploadRemoteFileOperation;
import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.FileStorageUtils;
@ -64,6 +66,7 @@ public class UploadFileOperation extends RemoteOperation {
private OCFile mFile; private OCFile mFile;
private OCFile mOldFile; private OCFile mOldFile;
private String mRemotePath = null; private String mRemotePath = null;
private boolean mChunked = false;
private boolean mIsInstant = false; private boolean mIsInstant = false;
private boolean mRemoteFolderToBeCreated = false; private boolean mRemoteFolderToBeCreated = false;
private boolean mForceOverwrite = false; private boolean mForceOverwrite = false;
@ -72,7 +75,6 @@ public class UploadFileOperation extends RemoteOperation {
private String mOriginalFileName = null; private String mOriginalFileName = null;
private String mOriginalStoragePath = null; private String mOriginalStoragePath = null;
PutMethod mPutMethod = null; PutMethod mPutMethod = null;
private OnDatatransferProgressListener mDataTransferListener;
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>(); private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
private Context mContext; private Context mContext;
@ -84,11 +86,11 @@ public class UploadFileOperation extends RemoteOperation {
public UploadFileOperation( Account account, public UploadFileOperation( Account account,
OCFile file, OCFile file,
boolean chunked,
boolean isInstant, boolean isInstant,
boolean forceOverwrite, boolean forceOverwrite,
int localBehaviour, int localBehaviour,
Context context, Context context) {
OnDatatransferProgressListener listener) {
if (account == null) if (account == null)
throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation"); throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation");
if (file == null) if (file == null)
@ -103,13 +105,13 @@ public class UploadFileOperation extends RemoteOperation {
mAccount = account; mAccount = account;
mFile = file; mFile = file;
mRemotePath = file.getRemotePath(); mRemotePath = file.getRemotePath();
mChunked = chunked;
mIsInstant = isInstant; mIsInstant = isInstant;
mForceOverwrite = forceOverwrite; mForceOverwrite = forceOverwrite;
mLocalBehaviour = localBehaviour; mLocalBehaviour = localBehaviour;
mOriginalStoragePath = mFile.getStoragePath(); mOriginalStoragePath = mFile.getStoragePath();
mOriginalFileName = mFile.getFileName(); mOriginalFileName = mFile.getFileName();
mContext = context; mContext = context;
mDataTransferListener = listener;
} }
public Account getAccount() { public Account getAccount() {
@ -271,8 +273,17 @@ public class UploadFileOperation extends RemoteOperation {
localCopyPassed = true; localCopyPassed = true;
/// perform the upload /// perform the upload
if (mChunked) {
mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(),
mFile.getMimetype());
} else {
mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(), mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(),
mFile.getMimetype()); mFile.getMimetype());
}
Iterator <OnDatatransferProgressListener> listener = mDataTransferListeners.iterator();
while (listener.hasNext()) {
mUploadOperation.addDatatransferProgressListener(listener.next());
}
result = mUploadOperation.execute(client); result = mUploadOperation.execute(client);
/// move local temporal file or original file to its corresponding /// move local temporal file or original file to its corresponding

View file

@ -28,9 +28,6 @@ import java.util.Vector;
import com.owncloud.android.MainApp; import com.owncloud.android.MainApp;
import com.owncloud.android.R; import com.owncloud.android.R;
import com.owncloud.android.R.id;
import com.owncloud.android.R.layout;
import com.owncloud.android.R.string;
import com.owncloud.android.authentication.AccountAuthenticator; import com.owncloud.android.authentication.AccountAuthenticator;
import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.datamodel.OCFile;