diff --git a/oc_framework-test-project/AndroidManifest.xml b/oc_framework-test-project/AndroidManifest.xml index c913bf0668..2d296ede8e 100644 --- a/oc_framework-test-project/AndroidManifest.xml +++ b/oc_framework-test-project/AndroidManifest.xml @@ -9,7 +9,9 @@ - + + + . + * + */ + +package com.owncloud.android.oc_framework_test_project.test; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.SimpleDateFormat; +import java.util.Date; + +import android.content.res.AssetManager; +import android.os.Environment; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; + +import com.owncloud.android.oc_framework.operations.RemoteOperationResult; +import com.owncloud.android.oc_framework_test_project.TestActivity; + +/** + * Class to test Update File Operation + * @author masensio + * + */ + +public class UploadFileTest extends ActivityInstrumentationTestCase2 { + + /* Files to upload. These files must exists on the device */ + private final String mFileToUpload = "fileToUpload.png"; + private final String mMimeType = "image/png"; + + private final String mFileToUploadWithChunks = "fileToUploadChunks.MP4"; + private final String mMimeTypeWithChunks = "video/mp4"; + + private final String mFileNotFound = "fileNotFound.png"; + + private final String mStoragePath = "/owncloud/tmp/uploadTest"; + private String mPath; + + private String mCurrentDate; + + private TestActivity mActivity; + + public UploadFileTest() { + super(TestActivity.class); + + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + setActivityInitialTouchMode(false); + mActivity = getActivity(); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); + mCurrentDate = sdf.format(new Date()); + + File sdCard = Environment.getExternalStorageDirectory(); + mPath = sdCard.getAbsolutePath() + "/" + mStoragePath + mCurrentDate; + + //mActivity.createFolder(mPath, true); + + copyAssets(); + } + + /** + * Copy Files to ulpload to SdCard + */ + private void copyAssets() { + AssetManager assetManager = getActivity().getAssets(); + String[] files = { mFileToUpload, mFileToUploadWithChunks }; + + // Folder with contents + File folder = new File(mPath); + folder.mkdirs(); + + + for(String filename : files) { + InputStream in = null; + OutputStream out = null; + try { + in = assetManager.open(filename); + File outFile = new File(folder, filename); + out = new FileOutputStream(outFile); + copyFile(in, out); + in.close(); + in = null; + out.flush(); + out.close(); + out = null; + } catch(IOException e) { + Log.e("tag", "Failed to copy asset file: " + filename, e); + } + } + } + + private void copyFile(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[1024]; + int read; + while((read = in.read(buffer)) != -1){ + out.write(buffer, 0, read); + } + } + + + /** + * Test Upload File without chunks + */ + public void testUploadFile() { + + String storagePath = mPath + "/" + mFileToUpload; + //String remotePath = "/uploadTest" + mCurrentDate + "/" + mFileToUpload; + String remotePath = "/" + mFileToUpload; + + RemoteOperationResult result = mActivity.uploadFile(storagePath, remotePath, mMimeType); + assertTrue(result.isSuccess()); + } + + /** + * Test Upload File with chunks + */ + public void testUploadFileWithChunks() { + + String storagePath = mPath + "/" + mFileToUploadWithChunks; + //String remotePath = "/uploadTest" + mCurrentDate + "/" +mFileToUploadWithChunks; + String remotePath = "/" + mFileToUploadWithChunks; + + RemoteOperationResult result = mActivity.uploadFile(storagePath, remotePath, mMimeTypeWithChunks); + assertTrue(result.isSuccess()); + } + + /** + * Test Upload Not Found File + */ + public void testUploadFileNotFound() { + + String storagePath = mPath + "/" + mFileNotFound; + //String remotePath = "/uploadTest" + mCurrentDate + "/" + mFileToUpload; + String remotePath = "/" + mFileNotFound; + + RemoteOperationResult result = mActivity.uploadFile(storagePath, remotePath, mMimeType); + assertFalse(result.isSuccess()); + } + +} diff --git a/oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java b/oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java index db38ea5cfb..c42aca2e62 100644 --- a/oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java +++ b/oc_framework-test-project/src/com/owncloud/android/oc_framework_test_project/TestActivity.java @@ -3,10 +3,12 @@ package com.owncloud.android.oc_framework_test_project; import com.owncloud.android.oc_framework.network.webdav.OwnCloudClientFactory; import com.owncloud.android.oc_framework.network.webdav.WebdavClient; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; +import com.owncloud.android.oc_framework.operations.remote.ChunkedUploadRemoteFileOperation; import com.owncloud.android.oc_framework.operations.remote.CreateRemoteFolderOperation; import com.owncloud.android.oc_framework.operations.remote.ReadRemoteFolderOperation; import com.owncloud.android.oc_framework.operations.remote.RemoveRemoteFileOperation; import com.owncloud.android.oc_framework.operations.remote.RenameRemoteFileOperation; +import com.owncloud.android.oc_framework.operations.remote.UploadRemoteFileOperation; import android.net.Uri; import android.os.Bundle; @@ -24,6 +26,7 @@ public class TestActivity extends Activity { private static final String mServerUri = "https://beta.owncloud.com/owncloud/remote.php/webdav"; private static final String mUser = "testandroid"; private static final String mPass = "testandroid"; + private static final boolean mChunked = true; //private Account mAccount = null; private WebdavClient mClient; @@ -105,4 +108,24 @@ public class TestActivity extends Activity { return result; } + /** Access to the library method to Upload a File + * @param storagePath + * @param remotePath + * @param mimeType + * + * @return + */ + public RemoteOperationResult uploadFile(String storagePath, String remotePath, String mimeType) { + + UploadRemoteFileOperation uploadOperation; + if (mChunked) { + uploadOperation = new ChunkedUploadRemoteFileOperation(storagePath, remotePath, mimeType); + } else { + uploadOperation = new UploadRemoteFileOperation(storagePath, remotePath, mimeType); + } + + RemoteOperationResult result = uploadOperation.execute(mClient); + + return result; + } } diff --git a/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ChunkedUploadRemoteFileOperation.java similarity index 72% rename from src/com/owncloud/android/operations/ChunkedUploadFileOperation.java rename to oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ChunkedUploadRemoteFileOperation.java index 9e4e1ade10..4df5fea6ec 100644 --- a/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java +++ b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ChunkedUploadRemoteFileOperation.java @@ -16,7 +16,7 @@ * */ -package com.owncloud.android.operations; +package com.owncloud.android.oc_framework.operations.remote; import java.io.File; import java.io.IOException; @@ -27,32 +27,25 @@ import java.util.Random; import org.apache.commons.httpclient.HttpException; 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.webdav.ChunkFromFileChannelRequestEntity; import com.owncloud.android.oc_framework.network.webdav.WebdavClient; import com.owncloud.android.oc_framework.network.webdav.WebdavUtils; -import com.owncloud.android.utils.Log_OC; -import android.accounts.Account; +import android.util.Log; -public class ChunkedUploadFileOperation extends UploadFileOperation { +public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation { public static final long CHUNK_SIZE = 1024000; private static final String OC_CHUNKED_HEADER = "OC-Chunked"; - private static final String TAG = ChunkedUploadFileOperation.class.getSimpleName(); - - public ChunkedUploadFileOperation( Account account, - OCFile file, - boolean isInstant, - boolean forceOverwrite, - int localBehaviour) { - - super(account, file, isInstant, forceOverwrite, localBehaviour); - } + private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); + public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) { + super(storagePath, remotePath, mimeType); + } + @Override protected int uploadFile(WebdavClient client) throws HttpException, IOException { int status = -1; @@ -60,13 +53,17 @@ public class ChunkedUploadFileOperation extends UploadFileOperation { FileChannel channel = null; RandomAccessFile raf = null; try { - File file = new File(getStoragePath()); + File file = new File(mStoragePath); raf = new RandomAccessFile(file, "r"); channel = raf.getChannel(); - mEntity = new ChunkFromFileChannelRequestEntity(channel, getMimeType(), CHUNK_SIZE, file); - ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners()); + mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file); + //((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners()); + synchronized (mDataTransferListeners) { + ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners); + } + 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); for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) { if (mPutMethod != null) { @@ -78,7 +75,7 @@ public class ChunkedUploadFileOperation extends UploadFileOperation { mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); 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)) break; } diff --git a/src/com/owncloud/android/operations/ExistenceCheckOperation.java b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ExistenceCheckRemoteOperation.java similarity index 80% rename from src/com/owncloud/android/operations/ExistenceCheckOperation.java rename to oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ExistenceCheckRemoteOperation.java index d92190c1f8..88e6e81dfc 100644 --- a/src/com/owncloud/android/operations/ExistenceCheckOperation.java +++ b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ExistenceCheckRemoteOperation.java @@ -15,7 +15,7 @@ * */ -package com.owncloud.android.operations; +package com.owncloud.android.oc_framework.operations.remote; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.HeadMethod; @@ -24,22 +24,22 @@ import com.owncloud.android.oc_framework.network.webdav.WebdavClient; import com.owncloud.android.oc_framework.operations.RemoteOperation; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.oc_framework.network.webdav.WebdavUtils; -import com.owncloud.android.utils.Log_OC; import android.content.Context; import android.net.ConnectivityManager; +import android.util.Log; /** * Operation to check the existence or absence of a path in a remote server. * * @author David A. Velasco */ -public class ExistenceCheckOperation extends RemoteOperation { +public class ExistenceCheckRemoteOperation extends RemoteOperation { /** Maximum time to wait for a response from the server in MILLISECONDs. */ public static final int TIMEOUT = 10000; - private static final String TAG = ExistenceCheckOperation.class.getSimpleName(); + private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName(); private String mPath; private Context mContext; @@ -53,7 +53,7 @@ public class ExistenceCheckOperation extends RemoteOperation { * @param context Android application context. * @param successIfAbsent When 'true', the operation finishes in success if the path does NOT exist in the remote server (HTTP 404). */ - public ExistenceCheckOperation(String path, Context context, boolean successIfAbsent) { + public ExistenceCheckRemoteOperation(String path, Context context, boolean successIfAbsent) { mPath = (path != null) ? path : ""; mContext = context; mSuccessIfAbsent = successIfAbsent; @@ -73,11 +73,11 @@ public class ExistenceCheckOperation extends RemoteOperation { client.exhaustResponse(head.getResponseBodyAsStream()); boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent); result = new RemoteOperationResult(success, status, head.getResponseHeaders()); - Log_OC.d(TAG, "Existence check for " + client.getBaseUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + "finished with HTTP status " + status + (!success?"(FAIL)":"")); + Log.d(TAG, "Existence check for " + client.getBaseUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + "finished with HTTP status " + status + (!success?"(FAIL)":"")); } catch (Exception e) { result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Existence check for " + client.getBaseUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException()); + Log.e(TAG, "Existence check for " + client.getBaseUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException()); } finally { if (head != null) diff --git a/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/UploadRemoteFileOperation.java b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/UploadRemoteFileOperation.java new file mode 100644 index 0000000000..91e21b494d --- /dev/null +++ b/oc_framework/src/com/owncloud/android/oc_framework/operations/remote/UploadRemoteFileOperation.java @@ -0,0 +1,147 @@ +/* ownCloud Android client application + * Copyright (C) 2012-2013 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.oc_framework.operations.remote; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.commons.httpclient.methods.RequestEntity; +import org.apache.http.HttpStatus; + +import com.owncloud.android.oc_framework.network.ProgressiveDataTransferer; +import com.owncloud.android.oc_framework.network.webdav.FileRequestEntity; +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.WebdavUtils; +import com.owncloud.android.oc_framework.operations.OperationCancelledException; +import com.owncloud.android.oc_framework.operations.RemoteOperation; +import com.owncloud.android.oc_framework.operations.RemoteOperationResult; + +/** + * Remote operation performing the upload of a remote file to the ownCloud server. + * + * @author David A. Velasco + * @author masensio + */ + +public class UploadRemoteFileOperation extends RemoteOperation { + + + protected String mStoragePath; + protected String mRemotePath; + protected String mMimeType; + protected PutMethod mPutMethod = null; + + private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); + protected Set mDataTransferListeners = new HashSet(); + + protected RequestEntity mEntity = null; + + public UploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) { + mStoragePath = storagePath; + mRemotePath = remotePath; + mMimeType = mimeType; + } + + @Override + protected RemoteOperationResult run(WebdavClient client) { + RemoteOperationResult result = null; + + try { + // / perform the upload + synchronized (mCancellationRequested) { + if (mCancellationRequested.get()) { + throw new OperationCancelledException(); + } else { + mPutMethod = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath)); + } + } + + int status = uploadFile(client); + + result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); + + } catch (Exception e) { + // TODO something cleaner with cancellations + if (mCancellationRequested.get()) { + result = new RemoteOperationResult(new OperationCancelledException()); + } else { + result = new RemoteOperationResult(e); + } + } + return result; + } + + public boolean isSuccess(int status) { + return ((status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT)); + } + + protected int uploadFile(WebdavClient client) throws HttpException, IOException, OperationCancelledException { + int status = -1; + try { + File f = new File(mStoragePath); + mEntity = new FileRequestEntity(f, mMimeType); + synchronized (mDataTransferListeners) { + ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners); + } + mPutMethod.setRequestEntity(mEntity); + status = client.executeMethod(mPutMethod); + client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); + + } finally { + mPutMethod.releaseConnection(); // let the connection available for other methods + } + return status; + } + + public Set getDataTransferListeners() { + return mDataTransferListeners; + } + + public void addDatatransferProgressListener (OnDatatransferProgressListener listener) { + synchronized (mDataTransferListeners) { + mDataTransferListeners.add(listener); + } + if (mEntity != null) { + ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListener(listener); + } + } + + public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) { + synchronized (mDataTransferListeners) { + mDataTransferListeners.remove(listener); + } + if (mEntity != null) { + ((ProgressiveDataTransferer)mEntity).removeDatatransferProgressListener(listener); + } + } + + public void cancel() { + synchronized (mCancellationRequested) { + mCancellationRequested.set(true); + if (mPutMethod != null) + mPutMethod.abort(); + } + } + +} diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index 85f4914a91..456e284ba5 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -57,13 +57,13 @@ import com.owncloud.android.oc_framework.accounts.AccountTypeUtils; import com.owncloud.android.oc_framework.accounts.OwnCloudAccount; import com.owncloud.android.oc_framework.network.webdav.OwnCloudClientFactory; import com.owncloud.android.oc_framework.network.webdav.WebdavClient; -import com.owncloud.android.operations.ExistenceCheckOperation; import com.owncloud.android.operations.OAuth2GetAccessToken; import com.owncloud.android.oc_framework.operations.OnRemoteOperationListener; import com.owncloud.android.operations.OwnCloudServerCheckOperation; import com.owncloud.android.oc_framework.operations.RemoteOperation; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.oc_framework.operations.remote.ExistenceCheckRemoteOperation; import com.owncloud.android.ui.dialog.SamlWebViewDialog; import com.owncloud.android.ui.dialog.SslValidatorDialog; import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener; @@ -131,7 +131,7 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList private final Handler mHandler = new Handler(); private Thread mOperationThread; private OwnCloudServerCheckOperation mOcServerChkOperation; - private ExistenceCheckOperation mAuthCheckOperation; + private ExistenceCheckRemoteOperation mAuthCheckOperation; private RemoteOperationResult mLastSslUntrustedServerResult; private Uri mNewCapturedUriFromOAuth2Redirection; @@ -716,7 +716,7 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList showDialog(DIALOG_LOGIN_PROGRESS); /// test credentials accessing the root folder - mAuthCheckOperation = new ExistenceCheckOperation("", this, false); + mAuthCheckOperation = new ExistenceCheckRemoteOperation("", this, false); WebdavClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(mHostBaseUrl + webdav_path), this, true); client.setBasicCredentials(username, password); mOperationThread = mAuthCheckOperation.execute(client, this, mHandler); @@ -765,7 +765,7 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList String webdav_path = AccountUtils.getWebdavPath(mDiscoveredVersion, mAuthTokenType); /// test credentials accessing the root folder - mAuthCheckOperation = new ExistenceCheckOperation("", this, false); + mAuthCheckOperation = new ExistenceCheckRemoteOperation("", this, false); WebdavClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(mHostBaseUrl + webdav_path), this, false); mOperationThread = mAuthCheckOperation.execute(client, this, mHandler); @@ -785,12 +785,12 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList } else if (operation instanceof OAuth2GetAccessToken) { onGetOAuthAccessTokenFinish((OAuth2GetAccessToken)operation, result); - } else if (operation instanceof ExistenceCheckOperation) { + } else if (operation instanceof ExistenceCheckRemoteOperation) { if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType)) { onSamlBasedFederatedSingleSignOnAuthorizationStart(operation, result); } else { - onAuthorizationCheckFinish((ExistenceCheckOperation)operation, result); + onAuthorizationCheckFinish((ExistenceCheckRemoteOperation)operation, result); } } } @@ -1084,7 +1084,7 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList /// time to test the retrieved access token on the ownCloud server mAuthToken = ((OAuth2GetAccessToken)operation).getResultTokenMap().get(OAuth2Constants.KEY_ACCESS_TOKEN); Log_OC.d(TAG, "Got ACCESS TOKEN: " + mAuthToken); - mAuthCheckOperation = new ExistenceCheckOperation("", this, false); + mAuthCheckOperation = new ExistenceCheckRemoteOperation("", this, false); WebdavClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(mHostBaseUrl + webdav_path), this, true); client.setBearerCredentials(mAuthToken); mAuthCheckOperation.execute(client, this, mHandler); @@ -1105,7 +1105,7 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList * @param operation Access check performed. * @param result Result of the operation. */ - private void onAuthorizationCheckFinish(ExistenceCheckOperation operation, RemoteOperationResult result) { + private void onAuthorizationCheckFinish(ExistenceCheckRemoteOperation operation, RemoteOperationResult result) { try { dismissDialog(DIALOG_LOGIN_PROGRESS); } catch (IllegalArgumentException e) { diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index e84b2d09c0..f38da6dcf4 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -38,17 +38,15 @@ import com.owncloud.android.authentication.AuthenticatorActivity; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.db.DbHandler; -import com.owncloud.android.operations.ChunkedUploadFileOperation; import com.owncloud.android.operations.CreateFolderOperation; -import com.owncloud.android.operations.ExistenceCheckOperation; import com.owncloud.android.oc_framework.operations.RemoteOperation; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; import com.owncloud.android.operations.UploadFileOperation; import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.oc_framework.operations.remote.ExistenceCheckRemoteOperation; import com.owncloud.android.oc_framework.utils.OwnCloudVersion; import com.owncloud.android.oc_framework.network.webdav.OnDatatransferProgressListener; import com.owncloud.android.oc_framework.accounts.OwnCloudAccount; -import com.owncloud.android.oc_framework.network.webdav.ChunkFromFileChannelRequestEntity; import com.owncloud.android.oc_framework.network.webdav.OwnCloudClientFactory; import com.owncloud.android.oc_framework.network.webdav.WebdavClient; import com.owncloud.android.oc_framework.network.webdav.WebdavEntry; @@ -253,7 +251,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i], ((mimeTypes != null) ? mimeTypes[i] : (String) null), storageManager); if (files[i] == null) { - // TODO @andomaex add failure Notiification + // TODO @andomaex add failure Notification return Service.START_NOT_STICKY; } } @@ -267,14 +265,15 @@ public class FileUploader extends Service implements OnDatatransferProgressListe try { for (int i = 0; i < files.length; i++) { uploadKey = buildRemoteName(account, files[i].getRemotePath()); - if (chunked - && (new File(files[i].getStoragePath())).length() > ChunkedUploadFileOperation.CHUNK_SIZE) // added to work around bug in servers 5.x - { - newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite, - localAction); - } else { - newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction); - } + newUpload = new UploadFileOperation(account, files[i], chunked, isInstant, forceOverwrite, localAction, + getApplicationContext()); +// if (chunked) { +// newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite, +// localAction, getApplicationContext()); +// } else { +// newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction, +// getApplicationContext()); +// } if (isInstant) { newUpload.setRemoteFolderToBeCreated(); } @@ -563,7 +562,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe * @return An {@link OCFile} instance corresponding to the folder where the file will be uploaded. */ private RemoteOperationResult grantFolderExistence(String pathToGrant) { - RemoteOperation operation = new ExistenceCheckOperation(pathToGrant, this, false); + RemoteOperation operation = new ExistenceCheckRemoteOperation(pathToGrant, this, false); RemoteOperationResult result = operation.execute(mUploadClient); if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND && mCurrentUpload.isRemoteFolderToBeCreated()) { operation = new CreateFolderOperation( pathToGrant, diff --git a/src/com/owncloud/android/operations/UploadFileOperation.java b/src/com/owncloud/android/operations/UploadFileOperation.java index 80a3463b37..b0b9466f6b 100644 --- a/src/com/owncloud/android/operations/UploadFileOperation.java +++ b/src/com/owncloud/android/operations/UploadFileOperation.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.HashSet; +import java.util.Iterator; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -38,15 +39,18 @@ import com.owncloud.android.oc_framework.network.ProgressiveDataTransferer; import com.owncloud.android.oc_framework.network.webdav.FileRequestEntity; 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.WebdavUtils; import com.owncloud.android.oc_framework.operations.OperationCancelledException; import com.owncloud.android.oc_framework.operations.RemoteOperation; import com.owncloud.android.oc_framework.operations.RemoteOperationResult; 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.UploadRemoteFileOperation; import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.Log_OC; import android.accounts.Account; +import android.content.Context; /** @@ -62,6 +66,7 @@ public class UploadFileOperation extends RemoteOperation { private OCFile mFile; private OCFile mOldFile; private String mRemotePath = null; + private boolean mChunked = false; private boolean mIsInstant = false; private boolean mRemoteFolderToBeCreated = false; private boolean mForceOverwrite = false; @@ -72,15 +77,20 @@ public class UploadFileOperation extends RemoteOperation { PutMethod mPutMethod = null; private Set mDataTransferListeners = new HashSet(); private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); + private Context mContext; + + private UploadRemoteFileOperation mUploadOperation; protected RequestEntity mEntity = null; public UploadFileOperation( Account account, OCFile file, + boolean chunked, boolean isInstant, boolean forceOverwrite, - int localBehaviour) { + int localBehaviour, + Context context) { if (account == null) throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation"); if (file == null) @@ -95,11 +105,13 @@ public class UploadFileOperation extends RemoteOperation { mAccount = account; mFile = file; mRemotePath = file.getRemotePath(); + mChunked = chunked; mIsInstant = isInstant; mForceOverwrite = forceOverwrite; mLocalBehaviour = localBehaviour; mOriginalStoragePath = mFile.getStoragePath(); mOriginalFileName = mFile.getFileName(); + mContext = context; } public Account getAccount() { @@ -199,7 +211,7 @@ public class UploadFileOperation extends RemoteOperation { // !!! expectedFile = new File(expectedPath); - // / check location of local file; if not the expected, copy to a + // check location of local file; if not the expected, copy to a // temporal file before upload (if COPY is the expected behaviour) if (!mOriginalStoragePath.equals(expectedPath) && mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY) { @@ -260,19 +272,23 @@ public class UploadFileOperation extends RemoteOperation { } localCopyPassed = true; - // / perform the upload - synchronized (mCancellationRequested) { - if (mCancellationRequested.get()) { - throw new OperationCancelledException(); - } else { - mPutMethod = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath())); - } + /// perform the upload + if (mChunked) { + mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(), + mFile.getMimetype()); + } else { + mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(), + mFile.getMimetype()); } - int status = uploadFile(client); + Iterator listener = mDataTransferListeners.iterator(); + while (listener.hasNext()) { + mUploadOperation.addDatatransferProgressListener(listener.next()); + } + result = mUploadOperation.execute(client); - // / move local temporal file or original file to its corresponding + /// move local temporal file or original file to its corresponding // location in the ownCloud local folder - if (isSuccess(status)) { + if (result.isSuccess()) { if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) { mFile.setStoragePath(null); @@ -305,8 +321,6 @@ public class UploadFileOperation extends RemoteOperation { } } - result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); - } catch (Exception e) { // TODO something cleaner with cancellations if (mCancellationRequested.get()) { @@ -358,28 +372,28 @@ public class UploadFileOperation extends RemoteOperation { mFile = newFile; } - public boolean isSuccess(int status) { - return ((status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT)); - } - - protected int uploadFile(WebdavClient client) throws HttpException, IOException, OperationCancelledException { - int status = -1; - try { - File f = new File(mFile.getStoragePath()); - mEntity = new FileRequestEntity(f, getMimeType()); - synchronized (mDataTransferListeners) { - ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners); - } - mPutMethod.setRequestEntity(mEntity); - status = client.executeMethod(mPutMethod); - client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); - - } finally { - mPutMethod.releaseConnection(); // let the connection available for - // other methods - } - return status; - } +// public boolean isSuccess(int status) { +// return ((status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT)); +// } +// +// protected int uploadFile(WebdavClient client) throws HttpException, IOException, OperationCancelledException { +// int status = -1; +// try { +// File f = new File(mFile.getStoragePath()); +// mEntity = new FileRequestEntity(f, getMimeType()); +// synchronized (mDataTransferListeners) { +// ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners); +// } +// mPutMethod.setRequestEntity(mEntity); +// status = client.executeMethod(mPutMethod); +// client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); +// +// } finally { +// mPutMethod.releaseConnection(); // let the connection available for +// // other methods +// } +// return status; +// } /** * Checks if remotePath does not exist in the server and returns it, or adds @@ -389,7 +403,7 @@ public class UploadFileOperation extends RemoteOperation { * @return */ private String getAvailableRemotePath(WebdavClient wc, String remotePath) throws Exception { - boolean check = wc.existsFile(remotePath); + boolean check = existsFile(wc, remotePath); if (!check) { return remotePath; } @@ -404,10 +418,12 @@ public class UploadFileOperation extends RemoteOperation { int count = 2; do { suffix = " (" + count + ")"; - if (pos >= 0) - check = wc.existsFile(remotePath + suffix + "." + extension); - else - check = wc.existsFile(remotePath + suffix); + if (pos >= 0) { + check = existsFile(wc, remotePath + suffix + "." + extension); + } + else { + check = existsFile(wc, remotePath + suffix); + } count++; } while (check); @@ -418,12 +434,14 @@ public class UploadFileOperation extends RemoteOperation { } } + private boolean existsFile(WebdavClient client, String remotePath){ + ExistenceCheckRemoteOperation existsOperation = new ExistenceCheckRemoteOperation(remotePath, mContext, false); + RemoteOperationResult result = existsOperation.execute(client); + return result.isSuccess(); + } + public void cancel() { - synchronized (mCancellationRequested) { - mCancellationRequested.set(true); - if (mPutMethod != null) - mPutMethod.abort(); - } + mUploadOperation.cancel(); } } diff --git a/src/com/owncloud/android/ui/activity/Uploader.java b/src/com/owncloud/android/ui/activity/Uploader.java index 08e2d21590..85c9e40d50 100644 --- a/src/com/owncloud/android/ui/activity/Uploader.java +++ b/src/com/owncloud/android/ui/activity/Uploader.java @@ -28,9 +28,6 @@ import java.util.Vector; import com.owncloud.android.MainApp; 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.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile;