1 /* ownCloud Android Library is available under MIT license
2 * Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
3 * Copyright (C) 2012 Bartek Przybylski
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 package com
.owncloud
.android
.oc_framework
.operations
;
28 import java
.io
.IOException
;
29 import java
.io
.Serializable
;
30 import java
.net
.MalformedURLException
;
31 import java
.net
.SocketException
;
32 import java
.net
.SocketTimeoutException
;
33 import java
.net
.UnknownHostException
;
34 import java
.util
.ArrayList
;
36 import javax
.net
.ssl
.SSLException
;
38 import org
.apache
.commons
.httpclient
.ConnectTimeoutException
;
39 import org
.apache
.commons
.httpclient
.Header
;
40 import org
.apache
.commons
.httpclient
.HttpException
;
41 import org
.apache
.commons
.httpclient
.HttpStatus
;
42 import org
.apache
.jackrabbit
.webdav
.DavException
;
43 import org
.json
.JSONException
;
45 import com
.owncloud
.android
.oc_framework
.accounts
.AccountUtils
.AccountNotFoundException
;
46 import com
.owncloud
.android
.oc_framework
.network
.CertificateCombinedException
;
48 import android
.accounts
.Account
;
49 import android
.accounts
.AccountsException
;
50 import android
.util
.Log
;
54 * The result of a remote operation required to an ownCloud server.
56 * Provides a common classification of remote operation results for all the
59 * @author David A. Velasco
61 public class RemoteOperationResult
implements Serializable
{
63 /** Generated - should be refreshed every time the class changes!! */
64 private static final long serialVersionUID
= -8257349554488668693L;
66 private static final String TAG
= "RemoteOperationResult";
68 public enum ResultCode
{
75 INSTANCE_NOT_CONFIGURED
,
81 NO_NETWORK_CONNECTION
,
83 SSL_RECOVERABLE_PEER_UNVERIFIED
,
86 INVALID_LOCAL_FILE_NAME
,
92 LOCAL_STORAGE_NOT_MOVED
,
93 LOCAL_STORAGE_NOT_COPIED
,
94 OAUTH2_ERROR_ACCESS_DENIED
,
100 INVALID_CHARACTER_IN_NAME
103 private boolean mSuccess
= false
;
104 private int mHttpCode
= -1;
105 private Exception mException
= null
;
106 private ResultCode mCode
= ResultCode
.UNKNOWN_ERROR
;
107 private String mRedirectedLocation
;
109 private ArrayList
<RemoteFile
> mFiles
;
111 public RemoteOperationResult(ResultCode code
) {
113 mSuccess
= (code
== ResultCode
.OK
|| code
== ResultCode
.OK_SSL
|| code
== ResultCode
.OK_NO_SSL
);
117 private RemoteOperationResult(boolean success
, int httpCode
) {
119 mHttpCode
= httpCode
;
122 mCode
= ResultCode
.OK
;
124 } else if (httpCode
> 0) {
126 case HttpStatus
.SC_UNAUTHORIZED
:
127 mCode
= ResultCode
.UNAUTHORIZED
;
129 case HttpStatus
.SC_NOT_FOUND
:
130 mCode
= ResultCode
.FILE_NOT_FOUND
;
132 case HttpStatus
.SC_INTERNAL_SERVER_ERROR
:
133 mCode
= ResultCode
.INSTANCE_NOT_CONFIGURED
;
135 case HttpStatus
.SC_CONFLICT
:
136 mCode
= ResultCode
.CONFLICT
;
138 case HttpStatus
.SC_INSUFFICIENT_STORAGE
:
139 mCode
= ResultCode
.QUOTA_EXCEEDED
;
142 mCode
= ResultCode
.UNHANDLED_HTTP_CODE
;
143 Log
.d(TAG
, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + httpCode
);
148 public RemoteOperationResult(boolean success
, int httpCode
, Header
[] headers
) {
149 this(success
, httpCode
);
150 if (headers
!= null
) {
152 for (int i
=0; i
<headers
.length
; i
++) {
153 current
= headers
[i
];
154 if ("Location".equals(current
.getName())) {
155 mRedirectedLocation
= current
.getValue();
162 public RemoteOperationResult(Exception e
) {
165 if (e
instanceof OperationCancelledException
) {
166 mCode
= ResultCode
.CANCELLED
;
168 } else if (e
instanceof SocketException
) {
169 mCode
= ResultCode
.WRONG_CONNECTION
;
171 } else if (e
instanceof SocketTimeoutException
) {
172 mCode
= ResultCode
.TIMEOUT
;
174 } else if (e
instanceof ConnectTimeoutException
) {
175 mCode
= ResultCode
.TIMEOUT
;
177 } else if (e
instanceof MalformedURLException
) {
178 mCode
= ResultCode
.INCORRECT_ADDRESS
;
180 } else if (e
instanceof UnknownHostException
) {
181 mCode
= ResultCode
.HOST_NOT_AVAILABLE
;
183 } else if (e
instanceof AccountNotFoundException
) {
184 mCode
= ResultCode
.ACCOUNT_NOT_FOUND
;
186 } else if (e
instanceof AccountsException
) {
187 mCode
= ResultCode
.ACCOUNT_EXCEPTION
;
189 } else if (e
instanceof SSLException
|| e
instanceof RuntimeException
) {
190 CertificateCombinedException se
= getCertificateCombinedException(e
);
193 if (se
.isRecoverable()) {
194 mCode
= ResultCode
.SSL_RECOVERABLE_PEER_UNVERIFIED
;
196 } else if (e
instanceof RuntimeException
) {
197 mCode
= ResultCode
.HOST_NOT_AVAILABLE
;
200 mCode
= ResultCode
.SSL_ERROR
;
204 mCode
= ResultCode
.UNKNOWN_ERROR
;
210 public void setData(ArrayList
<RemoteFile
> files
){
214 public ArrayList
<RemoteFile
> getData(){
218 public boolean isSuccess() {
222 public boolean isCancelled() {
223 return mCode
== ResultCode
.CANCELLED
;
226 public int getHttpCode() {
230 public ResultCode
getCode() {
234 public Exception
getException() {
238 public boolean isSslRecoverableException() {
239 return mCode
== ResultCode
.SSL_RECOVERABLE_PEER_UNVERIFIED
;
242 private CertificateCombinedException
getCertificateCombinedException(Exception e
) {
243 CertificateCombinedException result
= null
;
244 if (e
instanceof CertificateCombinedException
) {
245 return (CertificateCombinedException
) e
;
247 Throwable cause
= mException
.getCause();
248 Throwable previousCause
= null
;
249 while (cause
!= null
&& cause
!= previousCause
&& !(cause
instanceof CertificateCombinedException
)) {
250 previousCause
= cause
;
251 cause
= cause
.getCause();
253 if (cause
!= null
&& cause
instanceof CertificateCombinedException
) {
254 result
= (CertificateCombinedException
) cause
;
259 public String
getLogMessage() {
261 if (mException
!= null
) {
262 if (mException
instanceof OperationCancelledException
) {
263 return "Operation cancelled by the caller";
265 } else if (mException
instanceof SocketException
) {
266 return "Socket exception";
268 } else if (mException
instanceof SocketTimeoutException
) {
269 return "Socket timeout exception";
271 } else if (mException
instanceof ConnectTimeoutException
) {
272 return "Connect timeout exception";
274 } else if (mException
instanceof MalformedURLException
) {
275 return "Malformed URL exception";
277 } else if (mException
instanceof UnknownHostException
) {
278 return "Unknown host exception";
280 } else if (mException
instanceof CertificateCombinedException
) {
281 if (((CertificateCombinedException
) mException
).isRecoverable())
282 return "SSL recoverable exception";
284 return "SSL exception";
286 } else if (mException
instanceof SSLException
) {
287 return "SSL exception";
289 } else if (mException
instanceof DavException
) {
290 return "Unexpected WebDAV exception";
292 } else if (mException
instanceof HttpException
) {
293 return "HTTP violation";
295 } else if (mException
instanceof IOException
) {
296 return "Unrecovered transport exception";
298 } else if (mException
instanceof AccountNotFoundException
) {
299 Account failedAccount
= ((AccountNotFoundException
)mException
).getFailedAccount();
300 return mException
.getMessage() + " (" + (failedAccount
!= null ? failedAccount
.name
: "NULL") + ")";
302 } else if (mException
instanceof AccountsException
) {
303 return "Exception while using account";
305 } else if (mException
instanceof JSONException
) {
306 return "JSON exception";
309 return "Unexpected exception";
313 if (mCode
== ResultCode
.INSTANCE_NOT_CONFIGURED
) {
314 return "The ownCloud server is not configured!";
316 } else if (mCode
== ResultCode
.NO_NETWORK_CONNECTION
) {
317 return "No network connection";
319 } else if (mCode
== ResultCode
.BAD_OC_VERSION
) {
320 return "No valid ownCloud version was found at the server";
322 } else if (mCode
== ResultCode
.LOCAL_STORAGE_FULL
) {
323 return "Local storage full";
325 } else if (mCode
== ResultCode
.LOCAL_STORAGE_NOT_MOVED
) {
326 return "Error while moving file to final directory";
328 } else if (mCode
== ResultCode
.ACCOUNT_NOT_NEW
) {
329 return "Account already existing when creating a new one";
331 } else if (mCode
== ResultCode
.ACCOUNT_NOT_THE_SAME
) {
332 return "Authenticated with a different account than the one updating";
333 } else if (mCode
== ResultCode
.INVALID_CHARACTER_IN_NAME
) {
334 return "The file name contains an forbidden character";
337 return "Operation finished with HTTP status code " + mHttpCode
+ " (" + (isSuccess() ?
"success" : "fail") + ")";
341 public boolean isServerFail() {
342 return (mHttpCode
>= HttpStatus
.SC_INTERNAL_SERVER_ERROR
);
345 public boolean isException() {
346 return (mException
!= null
);
349 public boolean isTemporalRedirection() {
350 return (mHttpCode
== 302 || mHttpCode
== 307);
353 public String
getRedirectedLocation() {
354 return mRedirectedLocation
;
357 public boolean isIdPRedirection() {
358 return (mRedirectedLocation
!= null
&&
359 (mRedirectedLocation
.toUpperCase().contains("SAML") ||
360 mRedirectedLocation
.toLowerCase().contains("wayf")));