0ef5b31b53336e0400da7b98258c1e0e72ca8236
[pub/Android/ownCloud.git] / src / com / owncloud / android / operations / RemoteOperationResult.java
1 /* ownCloud Android client application
2 * Copyright (C) 2012 Bartek Przybylski
3 * Copyright (C) 2012-2013 ownCloud Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 package com.owncloud.android.operations;
21
22 import java.io.IOException;
23 import java.io.Serializable;
24 import java.net.MalformedURLException;
25 import java.net.SocketException;
26 import java.net.SocketTimeoutException;
27 import java.net.UnknownHostException;
28
29 import javax.net.ssl.SSLException;
30
31 import org.apache.commons.httpclient.ConnectTimeoutException;
32 import org.apache.commons.httpclient.HttpException;
33 import org.apache.commons.httpclient.HttpStatus;
34 import org.apache.jackrabbit.webdav.DavException;
35
36 import android.util.Log;
37
38 import com.owncloud.android.network.CertificateCombinedException;
39
40 /**
41 * The result of a remote operation required to an ownCloud server.
42 *
43 * Provides a common classification of remote operation results for all the
44 * application.
45 *
46 * @author David A. Velasco
47 */
48 public class RemoteOperationResult implements Serializable {
49
50 /** Generated - should be refreshed every time the class changes!! */
51 private static final long serialVersionUID = -7805531062432602444L;
52 private static final String TAG = "RemoteOperationResult";
53
54 public enum ResultCode {
55 OK, OK_SSL, OK_NO_SSL, UNHANDLED_HTTP_CODE, UNAUTHORIZED, FILE_NOT_FOUND, INSTANCE_NOT_CONFIGURED, UNKNOWN_ERROR, WRONG_CONNECTION, TIMEOUT, INCORRECT_ADDRESS, HOST_NOT_AVAILABLE, NO_NETWORK_CONNECTION, SSL_ERROR, SSL_RECOVERABLE_PEER_UNVERIFIED, BAD_OC_VERSION, CANCELLED, INVALID_LOCAL_FILE_NAME, INVALID_OVERWRITE, CONFLICT, SYNC_CONFLICT, LOCAL_STORAGE_FULL, LOCAL_STORAGE_NOT_MOVED, LOCAL_STORAGE_NOT_COPIED, QUOTA_EXCEEDED
56 }
57
58 private boolean mSuccess = false;
59 private int mHttpCode = -1;
60 private Exception mException = null;
61 private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
62
63 public RemoteOperationResult(ResultCode code) {
64 mCode = code;
65 mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL);
66 }
67
68 public RemoteOperationResult(boolean success, int httpCode) {
69 mSuccess = success;
70 mHttpCode = httpCode;
71
72 if (success) {
73 mCode = ResultCode.OK;
74
75 } else if (httpCode > 0) {
76 switch (httpCode) {
77 case HttpStatus.SC_UNAUTHORIZED:
78 mCode = ResultCode.UNAUTHORIZED;
79 break;
80 case HttpStatus.SC_NOT_FOUND:
81 mCode = ResultCode.FILE_NOT_FOUND;
82 break;
83 case HttpStatus.SC_INTERNAL_SERVER_ERROR:
84 mCode = ResultCode.INSTANCE_NOT_CONFIGURED;
85 break;
86 case HttpStatus.SC_CONFLICT:
87 mCode = ResultCode.CONFLICT;
88 break;
89 case HttpStatus.SC_INSUFFICIENT_STORAGE:
90 mCode = ResultCode.QUOTA_EXCEEDED;
91 break;
92 default:
93 mCode = ResultCode.UNHANDLED_HTTP_CODE;
94 Log.d(TAG, "RemoteOperationResult has prcessed UNHANDLED_HTTP_CODE: " + httpCode);
95 }
96 }
97 }
98
99 public RemoteOperationResult(Exception e) {
100 mException = e;
101
102 if (e instanceof OperationCancelledException) {
103 mCode = ResultCode.CANCELLED;
104
105 } else if (e instanceof SocketException) {
106 mCode = ResultCode.WRONG_CONNECTION;
107
108 } else if (e instanceof SocketTimeoutException) {
109 mCode = ResultCode.TIMEOUT;
110
111 } else if (e instanceof ConnectTimeoutException) {
112 mCode = ResultCode.TIMEOUT;
113
114 } else if (e instanceof MalformedURLException) {
115 mCode = ResultCode.INCORRECT_ADDRESS;
116
117 } else if (e instanceof UnknownHostException) {
118 mCode = ResultCode.HOST_NOT_AVAILABLE;
119
120 } else if (e instanceof SSLException || e instanceof RuntimeException) {
121 CertificateCombinedException se = getCertificateCombinedException(e);
122 if (se != null) {
123 mException = se;
124 if (se.isRecoverable()) {
125 mCode = ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
126 }
127 } else if (e instanceof RuntimeException) {
128 mCode = ResultCode.HOST_NOT_AVAILABLE;
129
130 } else {
131 mCode = ResultCode.SSL_ERROR;
132 }
133
134 } else {
135 mCode = ResultCode.UNKNOWN_ERROR;
136 }
137
138 }
139
140 public boolean isSuccess() {
141 return mSuccess;
142 }
143
144 public boolean isCancelled() {
145 return mCode == ResultCode.CANCELLED;
146 }
147
148 public int getHttpCode() {
149 return mHttpCode;
150 }
151
152 public ResultCode getCode() {
153 return mCode;
154 }
155
156 public Exception getException() {
157 return mException;
158 }
159
160 public boolean isSslRecoverableException() {
161 return mCode == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
162 }
163
164 private CertificateCombinedException getCertificateCombinedException(Exception e) {
165 CertificateCombinedException result = null;
166 if (e instanceof CertificateCombinedException) {
167 return (CertificateCombinedException) e;
168 }
169 Throwable cause = mException.getCause();
170 Throwable previousCause = null;
171 while (cause != null && cause != previousCause && !(cause instanceof CertificateCombinedException)) {
172 previousCause = cause;
173 cause = cause.getCause();
174 }
175 if (cause != null && cause instanceof CertificateCombinedException) {
176 result = (CertificateCombinedException) cause;
177 }
178 return result;
179 }
180
181 public String getLogMessage() {
182
183 if (mException != null) {
184 if (mException instanceof OperationCancelledException) {
185 return "Operation cancelled by the caller";
186
187 } else if (mException instanceof SocketException) {
188 return "Socket exception";
189
190 } else if (mException instanceof SocketTimeoutException) {
191 return "Socket timeout exception";
192
193 } else if (mException instanceof ConnectTimeoutException) {
194 return "Connect timeout exception";
195
196 } else if (mException instanceof MalformedURLException) {
197 return "Malformed URL exception";
198
199 } else if (mException instanceof UnknownHostException) {
200 return "Unknown host exception";
201
202 } else if (mException instanceof CertificateCombinedException) {
203 if (((CertificateCombinedException) mException).isRecoverable())
204 return "SSL recoverable exception";
205 else
206 return "SSL exception";
207
208 } else if (mException instanceof SSLException) {
209 return "SSL exception";
210
211 } else if (mException instanceof DavException) {
212 return "Unexpected WebDAV exception";
213
214 } else if (mException instanceof HttpException) {
215 return "HTTP violation";
216
217 } else if (mException instanceof IOException) {
218 return "Unrecovered transport exception";
219
220 } else {
221 return "Unexpected exception";
222 }
223 }
224
225 if (mCode == ResultCode.INSTANCE_NOT_CONFIGURED) {
226 return "The ownCloud server is not configured!";
227
228 } else if (mCode == ResultCode.NO_NETWORK_CONNECTION) {
229 return "No network connection";
230
231 } else if (mCode == ResultCode.BAD_OC_VERSION) {
232 return "No valid ownCloud version was found at the server";
233
234 } else if (mCode == ResultCode.LOCAL_STORAGE_FULL) {
235 return "Local storage full";
236
237 } else if (mCode == ResultCode.LOCAL_STORAGE_NOT_MOVED) {
238 return "Error while moving file to final directory";
239 }
240
241 return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")";
242
243 }
244
245 }