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