Updating synchronization for providing SSL warning when necessary; step 1: refactorin...
[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
34 import com.owncloud.android.network.CertificateCombinedException;
35
36
37 /**
38 * The result of a remote operation required to an ownCloud server.
39 *
40 * Provides a common classification of remote operation results for all the application.
41 *
42 * @author David A. Velasco
43 */
44 public class RemoteOperationResult implements Serializable {
45
46 /** Generated - to refresh every time the class changes */
47 private static final long serialVersionUID = -7805531062432602444L;
48
49
50 public enum ResultCode {
51 OK,
52 OK_SSL,
53 OK_NO_SSL,
54 UNHANDLED_HTTP_CODE,
55 UNAUTHORIZED,
56 FILE_NOT_FOUND,
57 INSTANCE_NOT_CONFIGURED,
58 UNKNOWN_ERROR,
59 WRONG_CONNECTION,
60 TIMEOUT,
61 INCORRECT_ADDRESS,
62 HOST_NOT_AVAILABLE,
63 NO_NETWORK_CONNECTION,
64 SSL_ERROR,
65 SSL_RECOVERABLE_PEER_UNVERIFIED,
66 BAD_OC_VERSION,
67 STORAGE_ERROR_MOVING_FROM_TMP,
68 CANCELLED
69 }
70
71 private boolean mSuccess = false;
72 private int mHttpCode = -1;
73 private Exception mException = null;
74 private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
75
76 public RemoteOperationResult(ResultCode code) {
77 mCode = code;
78 mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL);
79 }
80
81 public RemoteOperationResult(boolean success, int httpCode) {
82 mSuccess = success;
83 mHttpCode = httpCode;
84
85 if (success) {
86 mCode = ResultCode.OK;
87
88 } else if (httpCode > 0) {
89 switch (httpCode) {
90 case HttpStatus.SC_UNAUTHORIZED:
91 mCode = ResultCode.UNAUTHORIZED;
92 break;
93 case HttpStatus.SC_NOT_FOUND:
94 mCode = ResultCode.FILE_NOT_FOUND;
95 break;
96 case HttpStatus.SC_INTERNAL_SERVER_ERROR:
97 mCode = ResultCode.INSTANCE_NOT_CONFIGURED;
98 break;
99 default:
100 mCode = ResultCode.UNHANDLED_HTTP_CODE;
101 }
102 }
103 }
104
105 public RemoteOperationResult(Exception e) {
106 mException = e;
107
108 if (e instanceof OperationCancelledException) {
109 mCode = ResultCode.CANCELLED;
110
111 } else if (e instanceof SocketException) {
112 mCode = ResultCode.WRONG_CONNECTION;
113
114 } else if (e instanceof SocketTimeoutException) {
115 mCode = ResultCode.TIMEOUT;
116
117 } else if (e instanceof ConnectTimeoutException) {
118 mCode = ResultCode.TIMEOUT;
119
120 } else if (e instanceof MalformedURLException) {
121 mCode = ResultCode.INCORRECT_ADDRESS;
122
123 } else if (e instanceof UnknownHostException) {
124 mCode = ResultCode.HOST_NOT_AVAILABLE;
125
126 } else if (e instanceof SSLException || e instanceof RuntimeException) {
127 CertificateCombinedException se = getCertificateCombinedException(e);
128 if (se != null) {
129 mException = se;
130 if (se.isRecoverable()) {
131 mCode = ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
132 }
133
134 } else {
135 mCode = ResultCode.SSL_ERROR;
136 }
137
138 } else {
139 mCode = ResultCode.UNKNOWN_ERROR;
140 }
141
142 }
143
144
145 public boolean isSuccess() {
146 return mSuccess;
147 }
148
149 public boolean isCancelled() {
150 return mCode == ResultCode.CANCELLED;
151 }
152
153 public int getHttpCode() {
154 return mHttpCode;
155 }
156
157 public ResultCode getCode() {
158 return mCode;
159 }
160
161 public Exception getException() {
162 return mException;
163 }
164
165 public boolean isSslRecoverableException() {
166 return mCode == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
167 }
168
169 private CertificateCombinedException getCertificateCombinedException(Exception e) {
170 CertificateCombinedException result = null;
171 if (e instanceof CertificateCombinedException) {
172 return (CertificateCombinedException)e;
173 }
174 Throwable cause = mException.getCause();
175 Throwable previousCause = null;
176 while (cause != null && cause != previousCause && !(cause instanceof CertificateCombinedException)) {
177 previousCause = cause;
178 cause = cause.getCause();
179 }
180 if (cause != null && cause instanceof CertificateCombinedException) {
181 result = (CertificateCombinedException)cause;
182 }
183 return result;
184 }
185
186
187 public String getLogMessage() {
188
189 if (mException != null) {
190 if (mException instanceof OperationCancelledException) {
191 return "Operation cancelled by the caller";
192
193 } else if (mException instanceof SocketException) {
194 return "Socket exception";
195
196 } else if (mException instanceof SocketTimeoutException) {
197 return "Socket timeout exception";
198
199 } else if (mException instanceof ConnectTimeoutException) {
200 return "Connect timeout exception";
201
202 } else if (mException instanceof MalformedURLException) {
203 return "Malformed URL exception";
204
205 } else if (mException instanceof UnknownHostException) {
206 return "Unknown host exception";
207
208 } else if (mException instanceof SSLException) {
209 if (mCode == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED)
210 return "SSL recoverable exception";
211 else
212 return "SSL 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.STORAGE_ERROR_MOVING_FROM_TMP) {
235 return "Error while moving file from temporal to final directory";
236 }
237
238 return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess()?"success":"fail") + ")";
239
240 }
241
242 }