Loading src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +148 −2 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.owncloud.android.lib.resources.notifications.models.PushResponse; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavException; import org.json.JSONException; Loading @@ -57,7 +58,7 @@ import javax.net.ssl.SSLException; /** * The result of a remote operation required to an ownCloud server. * <p/> * * Provides a common classification of remote operation results for all the * application. * Loading Loading @@ -124,6 +125,7 @@ public class RemoteOperationResult implements Serializable { private boolean mSuccess = false; private int mHttpCode = -1; private String mHttpPhrase = null; private Exception mException = null; private ResultCode mCode = ResultCode.UNKNOWN_ERROR; private String mRedirectedLocation; Loading @@ -134,6 +136,13 @@ public class RemoteOperationResult implements Serializable { private List<Notification> mNotificationData; private PushResponse mPushResponse; /** * Public constructor from result code. * <p> * To be used when the caller takes the responsibility of interpreting the result of a {@link RemoteOperation} * * @param code {@link ResultCode} decided by the caller. */ public RemoteOperationResult(ResultCode code) { mCode = code; mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || Loading Loading @@ -228,9 +237,17 @@ public class RemoteOperationResult implements Serializable { httpCode); } } } /** * Public constructor from exception. * * To be used when an exception prevented the end of the {@link RemoteOperation}. * * Determines a {@link ResultCode} depending on the type of the exception. * * @param e Exception that interrupted the {@link RemoteOperation} */ public RemoteOperationResult(Exception e) { mException = e; Loading Loading @@ -278,9 +295,134 @@ public class RemoteOperationResult implements Serializable { } else { mCode = ResultCode.UNKNOWN_ERROR; } } /** * Public constructor from separate elements of an HTTP or DAV response. * * To be used when the result needs to be interpreted from the response of an HTTP/DAV method. * * Determines a {@link ResultCode} from the already executed method received as a parameter. Generally, * will depend on the HTTP code and HTTP response headers received. In some cases will inspect also the * response body. * * @param success The operation was considered successful or not. * @param httpMethod HTTP/DAV method already executed which response will be examined to interpret the * result. */ public RemoteOperationResult(boolean success, HttpMethod httpMethod) throws IOException { this( success, httpMethod.getStatusCode(), httpMethod.getStatusText(), httpMethod.getResponseHeaders() ); if (mHttpCode == HttpStatus.SC_BAD_REQUEST) { // 400 String bodyResponse = httpMethod.getResponseBodyAsString(); // do not get for other HTTP codes!; could not be available if (bodyResponse != null && bodyResponse.length() > 0) { InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); try { if (xmlParser.parseXMLResponse(is)) { mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER; } } catch (Exception e) { Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage()); // mCode stays as set in this(success, httpCode, headers) } } } } /** * Public constructor from separate elements of an HTTP or DAV response. * * To be used when the result needs to be interpreted from HTTP response elements that could come from * different requests (WARNING: black magic, try to avoid). * * If all the fields come from the same HTTP/DAV response, {@link #RemoteOperationResult(boolean, HttpMethod)} * should be used instead. * * Determines a {@link ResultCode} depending on the HTTP code and HTTP response headers received. * * @param success The operation was considered successful or not. * @param httpCode HTTP status code returned by an HTTP/DAV method. * @param httpPhrase HTTP status line phrase returned by an HTTP/DAV method * @param httpHeaders HTTP response header returned by an HTTP/DAV method */ public RemoteOperationResult(boolean success, int httpCode, String httpPhrase, Header[] httpHeaders) { this(success, httpCode, httpPhrase); if (httpHeaders != null) { Header current; for (Header httpHeader : httpHeaders) { current = httpHeader; if ("location".equals(current.getName().toLowerCase())) { mRedirectedLocation = current.getValue(); continue; } if ("www-authenticate".equals(current.getName().toLowerCase())) { mAuthenticate = current.getValue(); break; } } } if (isIdPRedirection()) { mCode = ResultCode.UNAUTHORIZED; // overrides default ResultCode.UNKNOWN } } /** * Private constructor for results built interpreting a HTTP or DAV response. * * Determines a {@link ResultCode} depending of the type of the exception. * * @param success Operation was successful or not. * @param httpCode HTTP status code returned by the HTTP/DAV method. * @param httpPhrase HTTP status line phrase returned by the HTTP/DAV method */ private RemoteOperationResult(boolean success, int httpCode, String httpPhrase) { mSuccess = success; mHttpCode = httpCode; mHttpPhrase = httpPhrase; if (success) { mCode = ResultCode.OK; } else if (httpCode > 0) { switch (httpCode) { case HttpStatus.SC_UNAUTHORIZED: // 401 mCode = ResultCode.UNAUTHORIZED; break; case HttpStatus.SC_FORBIDDEN: // 403 mCode = ResultCode.FORBIDDEN; break; case HttpStatus.SC_NOT_FOUND: // 404 mCode = ResultCode.FILE_NOT_FOUND; break; case HttpStatus.SC_CONFLICT: // 409 mCode = ResultCode.CONFLICT; break; case HttpStatus.SC_INTERNAL_SERVER_ERROR: // 500 mCode = ResultCode.INSTANCE_NOT_CONFIGURED; // assuming too much... break; case HttpStatus.SC_SERVICE_UNAVAILABLE: // 503 mCode = ResultCode.MAINTENANCE_MODE; break; case HttpStatus.SC_INSUFFICIENT_STORAGE: // 507 mCode = ResultCode.QUOTA_EXCEEDED; break; default: mCode = ResultCode.UNHANDLED_HTTP_CODE; // UNKNOWN ERROR Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + mHttpCode + " " + mHttpPhrase); } } } public void setData(ArrayList<Object> files) { mData = files; Loading Loading @@ -318,6 +460,10 @@ public class RemoteOperationResult implements Serializable { return mHttpCode; } public String getHttpPhrase() { return mHttpPhrase; } public ResultCode getCode() { return mCode; } Loading src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +17 −21 Original line number Diff line number Diff line Loading @@ -31,15 +31,13 @@ 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.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.methods.PutMethod; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.util.Calendar; Loading Loading @@ -70,8 +68,9 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation } @Override protected int uploadFile(OwnCloudClient client) throws IOException { protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOException { int status = -1; RemoteOperationResult result = null; FileChannel channel = null; RandomAccessFile raf = null; Loading Loading @@ -136,19 +135,7 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation status = client.executeMethod(mPutMethod); if (status == 400) { InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); InputStream is = new ByteArrayInputStream( mPutMethod.getResponseBodyAsString().getBytes()); try { mForbiddenCharsInServer = xmlParser.parseXMLResponse(is); } catch (Exception e) { mForbiddenCharsInServer = false; Log_OC.e(TAG, "Exception reading exception from server", e); } } result = new RemoteOperationResult(isSuccess(status), mPutMethod); client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + Loading @@ -173,13 +160,22 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation } if (channel != null) try { channel.close(); if (raf != null) } catch (IOException e) { Log_OC.e(TAG, "Error closing file channel!", e); } if (raf != null) { try { raf.close(); } catch (IOException e) { Log_OC.e(TAG, "Error closing file access!", e); } } if (mPutMethod != null) mPutMethod.releaseConnection(); // let the connection available for other methods } return status; return result; } private String getDateAsString() { Loading src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +8 −12 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ import java.io.IOException; /** * Remote operation moving a remote file or folder in the ownCloud server to a different folder * in the same account. * <p/> * * Allows renaming the moving file/folder at the same time. * * @author David A. Velasco Loading @@ -65,7 +65,7 @@ public class CopyRemoteFileOperation extends RemoteOperation { /** * Constructor. * <p/> * * TODO Paths should finish in "/" in the case of folders. ? * * @param srcRemotePath Remote path of the file/folder to move. Loading Loading @@ -134,18 +134,17 @@ public class CopyRemoteFileOperation extends RemoteOperation { client.exhaustResponse(copyMethod.getResponseBodyAsStream()); } Log.i(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); 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); Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage(), e); } finally { if (copyMethod != null) if (copyMethod != null) { copyMethod.releaseConnection(); } } return result; } Loading @@ -153,10 +152,10 @@ public class CopyRemoteFileOperation extends RemoteOperation { /** * Analyzes a multistatus response from the OC server to generate an appropriate result. * <p/> * * In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some * children are copied, some other aren't. * <p/> * * 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. Loading Loading @@ -193,12 +192,9 @@ public class CopyRemoteFileOperation extends RemoteOperation { } return result; } protected boolean isSuccess(int status) { return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT; } } src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +18 −39 Original line number Diff line number Diff line Loading @@ -24,30 +24,26 @@ package com.owncloud.android.lib.resources.files; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.params.HttpMethodParams; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.FileRequestEntity; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.network.ProgressiveDataTransferer; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.params.HttpMethodParams; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; /** * Remote operation performing the upload of a remote file to the ownCloud server. Loading @@ -69,7 +65,6 @@ public class UploadRemoteFileOperation extends RemoteOperation { protected String mMimeType; protected String mFileLastModifTimestamp; protected PutMethod mPutMethod = null; protected boolean mForbiddenCharsInServer = false; protected String mRequiredEtag = null; protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); Loading Loading @@ -112,14 +107,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { } else { // perform the upload int status = uploadFile(client); if (mForbiddenCharsInServer){ result = new RemoteOperationResult( RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER); } else { result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); } result = uploadFile(client); } } catch (Exception e) { Loading @@ -144,8 +132,10 @@ public class UploadRemoteFileOperation extends RemoteOperation { status == HttpStatus.SC_NO_CONTENT)); } protected int uploadFile(OwnCloudClient client) throws IOException { protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOException { int status = -1; RemoteOperationResult result; try { File f = new File(mLocalPath); mEntity = new FileRequestEntity(f, mMimeType); Loading @@ -161,25 +151,14 @@ public class UploadRemoteFileOperation extends RemoteOperation { mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); if (status == 400) { InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); InputStream is = new ByteArrayInputStream( mPutMethod.getResponseBodyAsString().getBytes()); try { mForbiddenCharsInServer = xmlParser.parseXMLResponse(is); } catch (Exception e) { mForbiddenCharsInServer = false; Log_OC.e(TAG, "Exception reading exception from server", e); } } result = new RemoteOperationResult(isSuccess(status), mPutMethod); client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); } finally { mPutMethod.releaseConnection(); // let the connection available for other methods } return status; return result; } public Set<OnDatatransferProgressListener> getDataTransferListeners() { Loading src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java +7 −15 Original line number Diff line number Diff line Loading @@ -85,11 +85,7 @@ public class GetRemoteStatusOperation extends RemoteOperation { client.setFollowRedirects(false); boolean isRedirectToNonSecureConnection = false; int status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT); mLatestResult = new RemoteOperationResult( (status == HttpStatus.SC_OK), status, get.getResponseHeaders() ); mLatestResult = new RemoteOperationResult((status == HttpStatus.SC_OK), get); String redirectedLocation = mLatestResult.getRedirectedLocation(); while (redirectedLocation != null && redirectedLocation.length() > 0 Loading @@ -102,11 +98,7 @@ public class GetRemoteStatusOperation extends RemoteOperation { get.releaseConnection(); get = new GetMethod(redirectedLocation); status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT); mLatestResult = new RemoteOperationResult( (status == HttpStatus.SC_OK), status, get.getResponseHeaders() ); mLatestResult = new RemoteOperationResult((status == HttpStatus.SC_OK), get); redirectedLocation = mLatestResult.getRedirectedLocation(); } Loading Loading
src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +148 −2 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.owncloud.android.lib.resources.notifications.models.PushResponse; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavException; import org.json.JSONException; Loading @@ -57,7 +58,7 @@ import javax.net.ssl.SSLException; /** * The result of a remote operation required to an ownCloud server. * <p/> * * Provides a common classification of remote operation results for all the * application. * Loading Loading @@ -124,6 +125,7 @@ public class RemoteOperationResult implements Serializable { private boolean mSuccess = false; private int mHttpCode = -1; private String mHttpPhrase = null; private Exception mException = null; private ResultCode mCode = ResultCode.UNKNOWN_ERROR; private String mRedirectedLocation; Loading @@ -134,6 +136,13 @@ public class RemoteOperationResult implements Serializable { private List<Notification> mNotificationData; private PushResponse mPushResponse; /** * Public constructor from result code. * <p> * To be used when the caller takes the responsibility of interpreting the result of a {@link RemoteOperation} * * @param code {@link ResultCode} decided by the caller. */ public RemoteOperationResult(ResultCode code) { mCode = code; mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || Loading Loading @@ -228,9 +237,17 @@ public class RemoteOperationResult implements Serializable { httpCode); } } } /** * Public constructor from exception. * * To be used when an exception prevented the end of the {@link RemoteOperation}. * * Determines a {@link ResultCode} depending on the type of the exception. * * @param e Exception that interrupted the {@link RemoteOperation} */ public RemoteOperationResult(Exception e) { mException = e; Loading Loading @@ -278,9 +295,134 @@ public class RemoteOperationResult implements Serializable { } else { mCode = ResultCode.UNKNOWN_ERROR; } } /** * Public constructor from separate elements of an HTTP or DAV response. * * To be used when the result needs to be interpreted from the response of an HTTP/DAV method. * * Determines a {@link ResultCode} from the already executed method received as a parameter. Generally, * will depend on the HTTP code and HTTP response headers received. In some cases will inspect also the * response body. * * @param success The operation was considered successful or not. * @param httpMethod HTTP/DAV method already executed which response will be examined to interpret the * result. */ public RemoteOperationResult(boolean success, HttpMethod httpMethod) throws IOException { this( success, httpMethod.getStatusCode(), httpMethod.getStatusText(), httpMethod.getResponseHeaders() ); if (mHttpCode == HttpStatus.SC_BAD_REQUEST) { // 400 String bodyResponse = httpMethod.getResponseBodyAsString(); // do not get for other HTTP codes!; could not be available if (bodyResponse != null && bodyResponse.length() > 0) { InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); try { if (xmlParser.parseXMLResponse(is)) { mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER; } } catch (Exception e) { Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage()); // mCode stays as set in this(success, httpCode, headers) } } } } /** * Public constructor from separate elements of an HTTP or DAV response. * * To be used when the result needs to be interpreted from HTTP response elements that could come from * different requests (WARNING: black magic, try to avoid). * * If all the fields come from the same HTTP/DAV response, {@link #RemoteOperationResult(boolean, HttpMethod)} * should be used instead. * * Determines a {@link ResultCode} depending on the HTTP code and HTTP response headers received. * * @param success The operation was considered successful or not. * @param httpCode HTTP status code returned by an HTTP/DAV method. * @param httpPhrase HTTP status line phrase returned by an HTTP/DAV method * @param httpHeaders HTTP response header returned by an HTTP/DAV method */ public RemoteOperationResult(boolean success, int httpCode, String httpPhrase, Header[] httpHeaders) { this(success, httpCode, httpPhrase); if (httpHeaders != null) { Header current; for (Header httpHeader : httpHeaders) { current = httpHeader; if ("location".equals(current.getName().toLowerCase())) { mRedirectedLocation = current.getValue(); continue; } if ("www-authenticate".equals(current.getName().toLowerCase())) { mAuthenticate = current.getValue(); break; } } } if (isIdPRedirection()) { mCode = ResultCode.UNAUTHORIZED; // overrides default ResultCode.UNKNOWN } } /** * Private constructor for results built interpreting a HTTP or DAV response. * * Determines a {@link ResultCode} depending of the type of the exception. * * @param success Operation was successful or not. * @param httpCode HTTP status code returned by the HTTP/DAV method. * @param httpPhrase HTTP status line phrase returned by the HTTP/DAV method */ private RemoteOperationResult(boolean success, int httpCode, String httpPhrase) { mSuccess = success; mHttpCode = httpCode; mHttpPhrase = httpPhrase; if (success) { mCode = ResultCode.OK; } else if (httpCode > 0) { switch (httpCode) { case HttpStatus.SC_UNAUTHORIZED: // 401 mCode = ResultCode.UNAUTHORIZED; break; case HttpStatus.SC_FORBIDDEN: // 403 mCode = ResultCode.FORBIDDEN; break; case HttpStatus.SC_NOT_FOUND: // 404 mCode = ResultCode.FILE_NOT_FOUND; break; case HttpStatus.SC_CONFLICT: // 409 mCode = ResultCode.CONFLICT; break; case HttpStatus.SC_INTERNAL_SERVER_ERROR: // 500 mCode = ResultCode.INSTANCE_NOT_CONFIGURED; // assuming too much... break; case HttpStatus.SC_SERVICE_UNAVAILABLE: // 503 mCode = ResultCode.MAINTENANCE_MODE; break; case HttpStatus.SC_INSUFFICIENT_STORAGE: // 507 mCode = ResultCode.QUOTA_EXCEEDED; break; default: mCode = ResultCode.UNHANDLED_HTTP_CODE; // UNKNOWN ERROR Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + mHttpCode + " " + mHttpPhrase); } } } public void setData(ArrayList<Object> files) { mData = files; Loading Loading @@ -318,6 +460,10 @@ public class RemoteOperationResult implements Serializable { return mHttpCode; } public String getHttpPhrase() { return mHttpPhrase; } public ResultCode getCode() { return mCode; } Loading
src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +17 −21 Original line number Diff line number Diff line Loading @@ -31,15 +31,13 @@ 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.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.methods.PutMethod; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.util.Calendar; Loading Loading @@ -70,8 +68,9 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation } @Override protected int uploadFile(OwnCloudClient client) throws IOException { protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOException { int status = -1; RemoteOperationResult result = null; FileChannel channel = null; RandomAccessFile raf = null; Loading Loading @@ -136,19 +135,7 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation status = client.executeMethod(mPutMethod); if (status == 400) { InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); InputStream is = new ByteArrayInputStream( mPutMethod.getResponseBodyAsString().getBytes()); try { mForbiddenCharsInServer = xmlParser.parseXMLResponse(is); } catch (Exception e) { mForbiddenCharsInServer = false; Log_OC.e(TAG, "Exception reading exception from server", e); } } result = new RemoteOperationResult(isSuccess(status), mPutMethod); client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + Loading @@ -173,13 +160,22 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation } if (channel != null) try { channel.close(); if (raf != null) } catch (IOException e) { Log_OC.e(TAG, "Error closing file channel!", e); } if (raf != null) { try { raf.close(); } catch (IOException e) { Log_OC.e(TAG, "Error closing file access!", e); } } if (mPutMethod != null) mPutMethod.releaseConnection(); // let the connection available for other methods } return status; return result; } private String getDateAsString() { Loading
src/com/owncloud/android/lib/resources/files/CopyRemoteFileOperation.java +8 −12 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ import java.io.IOException; /** * Remote operation moving a remote file or folder in the ownCloud server to a different folder * in the same account. * <p/> * * Allows renaming the moving file/folder at the same time. * * @author David A. Velasco Loading @@ -65,7 +65,7 @@ public class CopyRemoteFileOperation extends RemoteOperation { /** * Constructor. * <p/> * * TODO Paths should finish in "/" in the case of folders. ? * * @param srcRemotePath Remote path of the file/folder to move. Loading Loading @@ -134,18 +134,17 @@ public class CopyRemoteFileOperation extends RemoteOperation { client.exhaustResponse(copyMethod.getResponseBodyAsStream()); } Log.i(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); 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); Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage(), e); } finally { if (copyMethod != null) if (copyMethod != null) { copyMethod.releaseConnection(); } } return result; } Loading @@ -153,10 +152,10 @@ public class CopyRemoteFileOperation extends RemoteOperation { /** * Analyzes a multistatus response from the OC server to generate an appropriate result. * <p/> * * In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some * children are copied, some other aren't. * <p/> * * 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. Loading Loading @@ -193,12 +192,9 @@ public class CopyRemoteFileOperation extends RemoteOperation { } return result; } protected boolean isSuccess(int status) { return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT; } }
src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +18 −39 Original line number Diff line number Diff line Loading @@ -24,30 +24,26 @@ package com.owncloud.android.lib.resources.files; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.params.HttpMethodParams; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.FileRequestEntity; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.network.ProgressiveDataTransferer; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.PutMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.params.HttpMethodParams; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; /** * Remote operation performing the upload of a remote file to the ownCloud server. Loading @@ -69,7 +65,6 @@ public class UploadRemoteFileOperation extends RemoteOperation { protected String mMimeType; protected String mFileLastModifTimestamp; protected PutMethod mPutMethod = null; protected boolean mForbiddenCharsInServer = false; protected String mRequiredEtag = null; protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); Loading Loading @@ -112,14 +107,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { } else { // perform the upload int status = uploadFile(client); if (mForbiddenCharsInServer){ result = new RemoteOperationResult( RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER); } else { result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); } result = uploadFile(client); } } catch (Exception e) { Loading @@ -144,8 +132,10 @@ public class UploadRemoteFileOperation extends RemoteOperation { status == HttpStatus.SC_NO_CONTENT)); } protected int uploadFile(OwnCloudClient client) throws IOException { protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOException { int status = -1; RemoteOperationResult result; try { File f = new File(mLocalPath); mEntity = new FileRequestEntity(f, mMimeType); Loading @@ -161,25 +151,14 @@ public class UploadRemoteFileOperation extends RemoteOperation { mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); if (status == 400) { InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); InputStream is = new ByteArrayInputStream( mPutMethod.getResponseBodyAsString().getBytes()); try { mForbiddenCharsInServer = xmlParser.parseXMLResponse(is); } catch (Exception e) { mForbiddenCharsInServer = false; Log_OC.e(TAG, "Exception reading exception from server", e); } } result = new RemoteOperationResult(isSuccess(status), mPutMethod); client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); } finally { mPutMethod.releaseConnection(); // let the connection available for other methods } return status; return result; } public Set<OnDatatransferProgressListener> getDataTransferListeners() { Loading
src/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.java +7 −15 Original line number Diff line number Diff line Loading @@ -85,11 +85,7 @@ public class GetRemoteStatusOperation extends RemoteOperation { client.setFollowRedirects(false); boolean isRedirectToNonSecureConnection = false; int status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT); mLatestResult = new RemoteOperationResult( (status == HttpStatus.SC_OK), status, get.getResponseHeaders() ); mLatestResult = new RemoteOperationResult((status == HttpStatus.SC_OK), get); String redirectedLocation = mLatestResult.getRedirectedLocation(); while (redirectedLocation != null && redirectedLocation.length() > 0 Loading @@ -102,11 +98,7 @@ public class GetRemoteStatusOperation extends RemoteOperation { get.releaseConnection(); get = new GetMethod(redirectedLocation); status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT); mLatestResult = new RemoteOperationResult( (status == HttpStatus.SC_OK), status, get.getResponseHeaders() ); mLatestResult = new RemoteOperationResult((status == HttpStatus.SC_OK), get); redirectedLocation = mLatestResult.getRedirectedLocation(); } Loading