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