Commit 643d25be authored by vince-bourgmayer's avatar vince-bourgmayer
Browse files

remove DataTransfererProgressListener & co and add debug into RemoteOperation...

remove DataTransfererProgressListener & co and add debug into RemoteOperation to get query string just before its execution.
parent d51fa00f
......@@ -39,7 +39,6 @@ import android.widget.Toast;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientFactory;
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
......@@ -58,7 +57,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class MainActivity extends Activity implements OnRemoteOperationListener, OnDatatransferProgressListener {
public class MainActivity extends Activity implements OnRemoteOperationListener{
private static String LOG_TAG = MainActivity.class.getCanonicalName();
......@@ -164,7 +163,6 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
UploadFileRemoteOperation uploadOperation =
new UploadFileRemoteOperation(fileToUpload.getAbsolutePath(), remotePath, mimeType, timeStamp);
uploadOperation.addDatatransferProgressListener(this);
uploadOperation.execute(mClient, this, mHandler);
}
......@@ -183,7 +181,6 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
File fileToUpload = upFolder.listFiles()[0];
String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName();
DownloadFileRemoteOperation downloadOperation = new DownloadFileRemoteOperation(remotePath, downFolder.getAbsolutePath());
downloadOperation.addDatatransferProgressListener(this);
downloadOperation.execute(mClient, this, mHandler);
}
......@@ -258,25 +255,5 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
mFrame.setBackgroundDrawable(bDraw);
}
@Override
public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileName) {
final long percentage = (totalToTransfer > 0 ? totalTransferredSoFar * 100 / totalToTransfer : 0);
final boolean upload = fileName.contains(getString(R.string.upload_folder_path));
Log.d(LOG_TAG, "progressRate " + percentage);
mHandler.post(new Runnable() {
@Override
public void run() {
TextView progressView = null;
if (upload) {
progressView = findViewById(R.id.upload_progress);
} else {
progressView = findViewById(R.id.download_progress);
}
if (progressView != null) {
progressView.setText(Long.toString(percentage) + "%");
}
}
});
}
}
......@@ -45,7 +45,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
*
* @author David A. Velasco
*/
public class ChunkFromFileChannelRequestEntity implements RequestEntity, ProgressiveDataTransferer {
public class ChunkFromFileChannelRequestEntity implements RequestEntity{
private static final String TAG = ChunkFromFileChannelRequestEntity.class.getSimpleName();
......@@ -56,7 +56,6 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
private final File mFile;
private long mOffset;
private long mTransferred;
Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
private ByteBuffer mBuffer = ByteBuffer.allocate(4096);
public ChunkFromFileChannelRequestEntity(
......@@ -97,26 +96,7 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
return true;
}
@Override
public void addDatatransferProgressListener(OnDatatransferProgressListener listener) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.add(listener);
}
}
@Override
public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.addAll(listeners);
}
}
@Override
public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.remove(listener);
}
}
public void setmTransferred(long value) {
......@@ -125,7 +105,6 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
public void writeRequest(final OutputStream out) throws IOException {
int readCount = 0;
Iterator<OnDatatransferProgressListener> it = null;
try {
mChannel.position(mOffset);
......@@ -144,12 +123,6 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
if (mTransferred < maxCount) { // condition to avoid accumulate progress for repeated chunks
mTransferred += readCount;
}
synchronized (mDataTransferListeners) {
it = mDataTransferListeners.iterator();
while (it.hasNext()) {
it.next().onTransferProgress(readCount, mTransferred, size, mFile.getAbsolutePath());
}
}
}
} catch (IOException io) {
......
......@@ -47,11 +47,10 @@ import com.owncloud.android.lib.common.utils.Log_OC;
* A RequestEntity that represents a File.
*
*/
public class FileRequestEntity implements RequestEntity, ProgressiveDataTransferer {
public class FileRequestEntity implements RequestEntity {
final File mFile;
final String mContentType;
Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
public FileRequestEntity(final File file, final String contentType) {
super();
......@@ -77,27 +76,7 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
return true;
}
@Override
public void addDatatransferProgressListener(OnDatatransferProgressListener listener) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.add(listener);
}
}
@Override
public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.addAll(listeners);
}
}
@Override
public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.remove(listener);
}
}
@Override
public void writeRequest(final OutputStream out) throws IOException {
......@@ -106,7 +85,6 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
RandomAccessFile raf = new RandomAccessFile(mFile, "r");
FileChannel channel = raf.getChannel();
Iterator<OnDatatransferProgressListener> it = null;
long transferred = 0;
long size = mFile.length();
if (size == 0) size = -1;
......@@ -120,12 +98,6 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
}
tmp.clear();
transferred += readResult;
synchronized (mDataTransferListeners) {
it = mDataTransferListeners.iterator();
while (it.hasNext()) {
it.next().onTransferProgress(readResult, transferred, size, mFile.getAbsolutePath());
}
}
}
} catch (IOException io) {
......
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc.
* Copyright (C) 2012 Bartek Przybylski
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.network;
public interface OnDatatransferProgressListener {
public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileAbsoluteName);
}
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.network;
import java.util.Collection;
public interface ProgressiveDataTransferer {
public void addDatatransferProgressListener (OnDatatransferProgressListener listener);
public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners);
public void removeDatatransferProgressListener(OnDatatransferProgressListener listener);
}
......@@ -74,7 +74,7 @@ public abstract class RemoteOperation implements Runnable {
/** Callback object to notify about the execution of the remote operation */
private OnRemoteOperationListener mListener = null;
/** Handler to the thread where mListener methods will be called */
private Handler mListenerHandler = null;
......@@ -152,14 +152,14 @@ public abstract class RemoteOperation implements Runnable {
/**
* Asynchronously executes the remote operation
*
*
* This method should be used whenever an ownCloud account is available, instead of
* {@link #execute(OwnCloudClient)}.
*
*
* @deprecated This method will be removed in version 1.0.
* Use {@link #execute(Account, Context, OnRemoteOperationListener,
* Handler)} instead.
*
*
* @param account ownCloud account in remote ownCloud server to reach during
* the execution of the operation.
* @param context Android context for the component calling the method.
......@@ -183,9 +183,9 @@ public abstract class RemoteOperation implements Runnable {
mClient = null; // the client instance will be created from mAccount
// and mContext in the runnerThread to create below
mListener = listener;
mListenerHandler = listenerHandler;
Thread runnerThread = new Thread(this);
runnerThread.start();
return runnerThread;
......@@ -202,7 +202,7 @@ public abstract class RemoteOperation implements Runnable {
* execution of the operation.
* @param context Android context for the component calling the method.
* @param listener Listener to be notified about the execution of the operation.
* @param listenerHandler Handler associated to the thread where the methods of the listener
* @param listenerHandler Handler associated to the thread where the methods of the listener
* objects must be called.
* @return Thread were the remote operation is executed.
*/
......@@ -220,11 +220,11 @@ public abstract class RemoteOperation implements Runnable {
mCallerActivity = null;
mClient = null; // the client instance will be created from
// mAccount and mContext in the runnerThread to create below
mListener = listener;
mListenerHandler = listenerHandler;
Thread runnerThread = new Thread(this);
runnerThread.start();
return runnerThread;
......@@ -255,14 +255,14 @@ public abstract class RemoteOperation implements Runnable {
"without a listener to notiy the result");
}
mListener = listener;
if (listenerHandler == null) {
throw new IllegalArgumentException
("Trying to execute a remote operation asynchronously " +
"without a handler to the listener's thread");
}
mListenerHandler = listenerHandler;
Thread runnerThread = new Thread(this);
runnerThread.start();
return runnerThread;
......
......@@ -49,12 +49,7 @@ public abstract class OCSRemoteOperation extends RemoteOperation {
public ServerResponse<UserInfo> getServerResponse(HttpMethodBase method, Type type) throws IOException {
String response = method.getResponseBodyAsString();
/*JsonParser parser = new JsonParser();
JsonElement element = parser.parse(response);
Gson gson = new Gson();
return gson.fromJson(element, type.getType());*/
Moshi moshi = new Moshi.Builder().build();
JsonAdapter<ServerResponse<UserInfo>> jsonAdapter = moshi.adapter(type);
......
......@@ -29,7 +29,6 @@ import android.content.SharedPreferences;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity;
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
......@@ -86,10 +85,7 @@ public class ChunkedFileUploadRemoteOperation extends UploadFileRemoteOperation
raf = new RandomAccessFile(file, "r");
channel = raf.getChannel();
mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file);
synchronized (mDataTransferListeners) {
((ProgressiveDataTransferer)mEntity)
.addDatatransferProgressListeners(mDataTransferListeners);
}
long offset = 0;
String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) +
......
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
import org.apache.jackrabbit.webdav.Status;
import org.apache.jackrabbit.webdav.client.methods.CopyMethod;
import java.io.IOException;
/**
* Remote operation moving a remote file or folder in the ownCloud server to a different folder
* in the same account.
*
* Allows renaming the moving file/folder at the same time.
*
* @author David A. Velasco
*/
public class CopyFileRemoteOperation extends RemoteOperation {
private static final String TAG = CopyFileRemoteOperation.class.getSimpleName();
private static final int COPY_READ_TIMEOUT = 600000;
private static final int COPY_CONNECTION_TIMEOUT = 5000;
private String mSrcRemotePath;
private String mTargetRemotePath;
private boolean mOverwrite;
/**
* Constructor.
*
* TODO Paths should finish in "/" in the case of folders. ?
*
* @param srcRemotePath Remote path of the file/folder to move.
* @param targetRemotePath Remove path desired for the file/folder after moving it.
*/
public CopyFileRemoteOperation(String srcRemotePath, String targetRemotePath, boolean overwrite
) {
mSrcRemotePath = srcRemotePath;
mTargetRemotePath = targetRemotePath;
mOverwrite = overwrite;
}
/**
* Performs the rename operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
/// check parameters
if (mTargetRemotePath.equals(mSrcRemotePath)) {
// nothing to do!
return new RemoteOperationResult(ResultCode.OK);
}
if (mTargetRemotePath.startsWith(mSrcRemotePath)) {
return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT);
}
/// perform remote operation
CopyMethod copyMethod = null;
RemoteOperationResult result = null;
try {
copyMethod = new CopyMethod(
client.getWebdavUri() + WebdavUtils.encodePath(mSrcRemotePath),
client.getWebdavUri() + WebdavUtils.encodePath(mTargetRemotePath),
mOverwrite
);
int status = client.executeMethod(copyMethod, COPY_READ_TIMEOUT, COPY_CONNECTION_TIMEOUT);
/// process response
if (status == HttpStatus.SC_MULTI_STATUS) {
result = processPartialError(copyMethod);
} else if (status == HttpStatus.SC_PRECONDITION_FAILED && !mOverwrite) {
result = new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
client.exhaustResponse(copyMethod.getResponseBodyAsStream());
/// for other errors that could be explicitly handled, check first:
/// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
} else {
result = new RemoteOperationResult(isSuccess(status), copyMethod);
client.exhaustResponse(copyMethod.getResponseBodyAsStream());
}
Log.i(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage(), e);
} finally {
if (copyMethod != null) {
copyMethod.releaseConnection();
}
}
return result;
}
/**
* Analyzes a multistatus response from the OC server to generate an appropriate result.
*
* In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some
* children are copied, some other aren't.
*
* According to the WebDAV specification, a multistatus response SHOULD NOT include partial
* successes (201, 204) nor for descendants of already failed children (424) in the response
* entity. But SHOULD NOT != MUST NOT, so take carefully.
*
* @param copyMethod Copy operation just finished with a multistatus response
* @return A result for the {@link CopyFileRemoteOperation} caller
* @throws java.io.IOException If the response body could not be parsed
* @throws org.apache.jackrabbit.webdav.DavException If the status code is other than MultiStatus or if obtaining
* the response XML document fails
*/
private RemoteOperationResult processPartialError(CopyMethod copyMethod)
throws IOException, DavException {
// Adding a list of failed descendants to the result could be interesting; or maybe not.
// For the moment, let's take the easy way.
/// check that some error really occurred
MultiStatusResponse[] responses = copyMethod.getResponseBodyAsMultiStatus().getResponses();
Status[] status;
boolean failFound = false;
for (int i = 0; i < responses.length && !failFound; i++) {
status = responses[i].getStatus();
failFound = (
status != null &&
status.length > 0 &&
status[0].getStatusCode() > 299
);
}
RemoteOperationResult result;
if (failFound) {
result = new RemoteOperationResult(ResultCode.PARTIAL_COPY_DONE);
} else {
result = new RemoteOperationResult(true, copyMethod);
}
return result;
}
protected boolean isSuccess(int status) {
return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT;
}
}
......@@ -24,6 +24,8 @@
package com.owncloud.android.lib.resources.files;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
......@@ -90,6 +92,9 @@ public class CreateFolderRemoteOperation extends RemoteOperation {
MkColMethod mkCol = null;
try {
mkCol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
Log.d("CreateFolderRemoteOp", "Query string: "+mkCol.getQueryString());
client.setUseNextcloudUserAgent(true);
client.executeMethod(mkCol, READ_TIMEOUT, CONNECTION_TIMEOUT);
......
......@@ -24,8 +24,9 @@
package com.owncloud.android.lib.resources.files;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.network.WebdavUtils;