1.1 --- a/src/org/gege/caldavsyncadapter/caldav/CaldavFacade.java Tue Feb 10 21:55:00 2015 +0100 1.2 +++ b/src/org/gege/caldavsyncadapter/caldav/CaldavFacade.java Tue Feb 10 22:40:00 2015 +0100 1.3 @@ -1,6 +1,6 @@ 1.4 /** 1.5 * Copyright (c) 2012-2013, Gerald Garcia, David Wiesner, Timo Berger 1.6 - * 1.7 + * 1.8 * This file is part of Andoid Caldav Sync Adapter Free. 1.9 * 1.10 * Andoid Caldav Sync Adapter Free is free software: you can redistribute 1.11 @@ -16,31 +16,15 @@ 1.12 * You should have received a copy of the GNU General Public License 1.13 * along with Andoid Caldav Sync Adapter Free. 1.14 * If not, see <http://www.gnu.org/licenses/>. 1.15 - * 1.16 + * 1.17 */ 1.18 1.19 package org.gege.caldavsyncadapter.caldav; 1.20 1.21 -import java.io.BufferedReader; 1.22 -import java.io.ByteArrayInputStream; 1.23 -import java.io.FileNotFoundException; 1.24 -import java.io.IOException; 1.25 -import java.io.InputStream; 1.26 -import java.io.InputStreamReader; 1.27 -import java.io.UnsupportedEncodingException; 1.28 -import java.net.MalformedURLException; 1.29 -import java.net.SocketException; 1.30 -import java.net.URI; 1.31 -import java.net.URISyntaxException; 1.32 -import java.net.URL; 1.33 -import java.util.ArrayList; 1.34 -import java.util.List; 1.35 - 1.36 -import javax.xml.parsers.DocumentBuilder; 1.37 -import javax.xml.parsers.DocumentBuilderFactory; 1.38 -import javax.xml.parsers.ParserConfigurationException; 1.39 -import javax.xml.parsers.SAXParser; 1.40 -import javax.xml.parsers.SAXParserFactory; 1.41 +import android.accounts.Account; 1.42 +import android.content.ContentProviderClient; 1.43 +import android.content.Context; 1.44 +import android.util.Log; 1.45 1.46 import org.apache.http.HttpException; 1.47 import org.apache.http.HttpHost; 1.48 @@ -76,11 +60,12 @@ 1.49 import org.apache.http.params.HttpProtocolParams; 1.50 import org.apache.http.protocol.BasicHttpContext; 1.51 import org.apache.http.protocol.HttpContext; 1.52 +import org.apache.http.util.EntityUtils; 1.53 import org.gege.caldavsyncadapter.BuildConfig; 1.54 +import org.gege.caldavsyncadapter.caldav.entities.CalendarEvent; 1.55 +import org.gege.caldavsyncadapter.caldav.entities.CalendarList; 1.56 import org.gege.caldavsyncadapter.caldav.entities.DavCalendar; 1.57 import org.gege.caldavsyncadapter.caldav.entities.DavCalendar.CalendarSource; 1.58 -import org.gege.caldavsyncadapter.caldav.entities.CalendarEvent; 1.59 -import org.gege.caldavsyncadapter.caldav.entities.CalendarList; 1.60 import org.gege.caldavsyncadapter.caldav.http.HttpPropFind; 1.61 import org.gege.caldavsyncadapter.caldav.http.HttpReport; 1.62 import org.gege.caldavsyncadapter.caldav.xml.CalendarHomeHandler; 1.63 @@ -96,388 +81,410 @@ 1.64 import org.xml.sax.SAXException; 1.65 import org.xml.sax.XMLReader; 1.66 1.67 -import android.accounts.Account; 1.68 -import android.content.ContentProviderClient; 1.69 -import android.content.Context; 1.70 -import android.util.Log; 1.71 +import java.io.ByteArrayInputStream; 1.72 +import java.io.FileNotFoundException; 1.73 +import java.io.IOException; 1.74 +import java.io.InputStream; 1.75 +import java.io.UnsupportedEncodingException; 1.76 +import java.net.MalformedURLException; 1.77 +import java.net.SocketException; 1.78 +import java.net.URI; 1.79 +import java.net.URISyntaxException; 1.80 +import java.net.URL; 1.81 +import java.util.ArrayList; 1.82 +import java.util.List; 1.83 + 1.84 +import javax.net.ssl.SSLException; 1.85 +import javax.xml.parsers.DocumentBuilder; 1.86 +import javax.xml.parsers.DocumentBuilderFactory; 1.87 +import javax.xml.parsers.ParserConfigurationException; 1.88 +import javax.xml.parsers.SAXParser; 1.89 +import javax.xml.parsers.SAXParserFactory; 1.90 1.91 public class CaldavFacade { 1.92 - private static final String TAG = "CaldavFacade"; 1.93 + private static final String TAG = "CaldavFacade"; 1.94 1.95 - private final static String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 1.96 + private final static String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 1.97 1.98 - private String USER_AGENT = "CalDAV Sync Adapter (Android) https://github.com/gggard/AndroidCaldavSyncAdapater"; 1.99 - private String VERSION = ""; 1.100 + private String USER_AGENT = "CalDAV Sync Adapter (Android) https://github.com/gggard/AndroidCaldavSyncAdapater"; 1.101 + private String VERSION = ""; 1.102 1.103 - private static HttpClient httpClient; 1.104 - private HttpContext mContext = null; 1.105 - private AuthState mLastAuthState = null; 1.106 - private AuthScope mLastAuthScope = null; 1.107 - 1.108 - private boolean trustAll = true; 1.109 + private static HttpClient httpClient; 1.110 + private HttpContext mContext = null; 1.111 + private AuthState mLastAuthState = null; 1.112 + private AuthScope mLastAuthScope = null; 1.113 1.114 - private URL url; 1.115 + private boolean mTrustAll = true; 1.116 1.117 - private static HttpHost targetHost; 1.118 - 1.119 - private int lastStatusCode; 1.120 - private String lastETag; 1.121 - private String lastDav; 1.122 + private URL url; 1.123 1.124 - private String mstrcHeaderIfMatch = "If-Match"; 1.125 - private String mstrcHeaderIfNoneMatch = "If-None-Match"; 1.126 - 1.127 - private Account mAccount = null; 1.128 - private ContentProviderClient mProvider; 1.129 - 1.130 - protected HttpClient getHttpClient() { 1.131 + private static HttpHost targetHost; 1.132 1.133 - HttpParams params = new BasicHttpParams(); 1.134 - params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30); 1.135 - params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30)); 1.136 - params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false); 1.137 - HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 1.138 + private int lastStatusCode; 1.139 + private String lastETag; 1.140 + private String lastDav; 1.141 1.142 - SchemeRegistry registry = new SchemeRegistry(); 1.143 - registry.register(new Scheme("http", new PlainSocketFactory(), 80)); 1.144 - registry.register(new Scheme("https", (trustAll ? EasySSLSocketFactory.getSocketFactory() : SSLSocketFactory.getSocketFactory()), 443)); 1.145 - DefaultHttpClient client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, registry), params); 1.146 - 1.147 - return client; 1.148 - } 1.149 + private String mstrcHeaderIfMatch = "If-Match"; 1.150 + private String mstrcHeaderIfNoneMatch = "If-None-Match"; 1.151 1.152 - public CaldavFacade(String mUser, String mPassword, String mURL) throws MalformedURLException { 1.153 - url = new URL(mURL); 1.154 + private Account mAccount = null; 1.155 + private ContentProviderClient mProvider; 1.156 1.157 - httpClient = getHttpClient(); 1.158 - UsernamePasswordCredentials upc = new UsernamePasswordCredentials(mUser, mPassword); 1.159 + protected HttpClient getHttpClient() { 1.160 1.161 - AuthScope as = null; 1.162 - as = new AuthScope(url.getHost(), -1); 1.163 - ((AbstractHttpClient) httpClient).getCredentialsProvider().setCredentials(as, upc); 1.164 - 1.165 - mContext = new BasicHttpContext(); 1.166 - CredentialsProvider credProvider = ((AbstractHttpClient) httpClient).getCredentialsProvider(); 1.167 - mContext.setAttribute(ClientContext.CREDS_PROVIDER, credProvider); 1.168 - 1.169 - //http://dlinsin.blogspot.de/2009/08/http-basic-authentication-with-android.html 1.170 - ((AbstractHttpClient) httpClient).addRequestInterceptor(preemptiveAuth, 0); 1.171 + HttpParams params = new BasicHttpParams(); 1.172 + params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30); 1.173 + params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30)); 1.174 + params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false); 1.175 + HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 1.176 1.177 - String proto = "http"; 1.178 - int port = 80; 1.179 + SchemeRegistry registry = new SchemeRegistry(); 1.180 + registry.register(new Scheme("http", new PlainSocketFactory(), 80)); 1.181 + registry.register(new Scheme("https", (mTrustAll ? EasySSLSocketFactory.getSocketFactory() : SSLSocketFactory 1.182 + .getSocketFactory()), 443)); 1.183 + DefaultHttpClient client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, registry), params); 1.184 1.185 - if (url.getProtocol().equalsIgnoreCase("https")) { 1.186 - proto = "https"; 1.187 - if (url.getPort() == -1) 1.188 - port = 443; 1.189 - else 1.190 - port = url.getPort(); 1.191 - } 1.192 + return client; 1.193 + } 1.194 1.195 - if (url.getProtocol().equalsIgnoreCase("http")) { 1.196 - proto = "http"; 1.197 - if (url.getPort() == -1) 1.198 - port = 80; 1.199 - else 1.200 - port = url.getPort(); 1.201 - } 1.202 - targetHost = new HttpHost(url.getHost(), port, proto); 1.203 - } 1.204 - 1.205 - //http://dlinsin.blogspot.de/2009/08/http-basic-authentication-with-android.html 1.206 - HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() { 1.207 - @Override 1.208 - public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { 1.209 - AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); 1.210 + public CaldavFacade(String mUser, String mPassword, String mURL, String trustAll) throws MalformedURLException { 1.211 + url = new URL(mURL); 1.212 1.213 - if (authState.getAuthScheme() == null) { 1.214 - if (mLastAuthState != null) { 1.215 - Log.d(TAG, "LastAuthState: restored with user " + mLastAuthState.getCredentials().getUserPrincipal().getName()); 1.216 - authState.setAuthScheme(mLastAuthState.getAuthScheme()); 1.217 - authState.setCredentials(mLastAuthState.getCredentials()); 1.218 - } else { 1.219 - Log.d(TAG, "LastAuthState: nothing to do"); 1.220 - } 1.221 - if (mLastAuthScope != null) { 1.222 - authState.setAuthScope(mLastAuthScope); 1.223 - Log.d(TAG, "LastAuthScope: restored"); 1.224 - } else { 1.225 - Log.d(TAG, "LastAuthScope: nothing to do"); 1.226 - } 1.227 - } else { 1.228 - //AuthState and AuthScope have to be saved separate because of the AuthScope within AuthState gets lost, so we save it in a separate var. 1.229 - mLastAuthState = authState; 1.230 - Log.d(TAG, "LastAuthState: new with user " + mLastAuthState.getCredentials().getUserPrincipal().getName()); 1.231 - if (authState.getAuthScope() != null) { 1.232 - mLastAuthScope = authState.getAuthScope(); 1.233 - Log.d(TAG, "LastAuthScope: new"); 1.234 - } 1.235 - } 1.236 - } 1.237 - }; 1.238 + this.mTrustAll = Boolean.valueOf(trustAll); 1.239 1.240 - public enum TestConnectionResult { 1.241 - WRONG_CREDENTIAL, 1.242 - WRONG_URL, 1.243 - WRONG_SERVER_STATUS, 1.244 - WRONG_ANSWER, 1.245 - SUCCESS 1.246 - } 1.247 + httpClient = getHttpClient(); 1.248 + UsernamePasswordCredentials upc = new UsernamePasswordCredentials(mUser, mPassword); 1.249 1.250 - /** 1.251 - * TODO: testConnection should return only an instance of 1.252 - * TestConnectionResult without throwing an exception or only throw checked 1.253 - * exceptions so you don't have to check the result of this function AND 1.254 - * handle the exceptions 1.255 - * @param context 1.256 - * 1.257 - * @return {@link TestConnectionResult} 1.258 - * @throws HttpHostConnectException 1.259 - * @throws IOException 1.260 - * @throws URISyntaxException 1.261 - * @throws ParserConfigurationException 1.262 - * @throws SAXException 1.263 - */ 1.264 - public TestConnectionResult testConnection() throws HttpHostConnectException, IOException, URISyntaxException, ParserConfigurationException, SAXException { 1.265 - Log.d(TAG, "start testConnection "); 1.266 - try { 1.267 - List<DavCalendar> calendars = new ArrayList<DavCalendar>(); 1.268 - calendars = forceGetCalendarsFromUri(null, url.toURI()); 1.269 - if (calendars.size() != 0) { 1.270 - return TestConnectionResult.SUCCESS; 1.271 - } 1.272 + AuthScope as = null; 1.273 + as = new AuthScope(url.getHost(), -1); 1.274 + ((AbstractHttpClient) httpClient).getCredentialsProvider().setCredentials(as, upc); 1.275 1.276 - URI userPrincipal = getUserPrincipal(); 1.277 - List<URI> calendarSets = getCalendarHomes(userPrincipal); 1.278 - for (URI calendarSet : calendarSets) { 1.279 - List<DavCalendar> calendarSetCalendars = getCalendarsFromSet(calendarSet); 1.280 - calendars.addAll(calendarSetCalendars); 1.281 - } 1.282 - if (calendarSets.size() == 0) { 1.283 - return TestConnectionResult.WRONG_ANSWER; 1.284 - } 1.285 - } catch (FileNotFoundException e) { 1.286 - return TestConnectionResult.WRONG_URL; 1.287 - } catch (SocketException e) { 1.288 - return TestConnectionResult.WRONG_URL; 1.289 - } catch (AuthenticationException e) { 1.290 - return TestConnectionResult.WRONG_CREDENTIAL; 1.291 - } catch (ClientProtocolException e) { 1.292 - return TestConnectionResult.WRONG_SERVER_STATUS; 1.293 - } catch (CaldavProtocolException e) { 1.294 - return TestConnectionResult.WRONG_ANSWER; 1.295 - } 1.296 - return TestConnectionResult.SUCCESS; 1.297 - } 1.298 + mContext = new BasicHttpContext(); 1.299 + CredentialsProvider credProvider = ((AbstractHttpClient) httpClient).getCredentialsProvider(); 1.300 + mContext.setAttribute(ClientContext.CREDS_PROVIDER, credProvider); 1.301 1.302 - /** 1.303 - * @param context May be null if no notification is needed 1.304 - * @param uri 1.305 - * @return 1.306 - * @throws AuthenticationException 1.307 - * @throws FileNotFoundException 1.308 - */ 1.309 - private List<DavCalendar> forceGetCalendarsFromUri(Context context, URI uri) throws AuthenticationException, FileNotFoundException { 1.310 - List<DavCalendar> calendars = new ArrayList<DavCalendar>(); 1.311 - Exception exception = null; 1.312 - try { 1.313 - calendars = getCalendarsFromSet(uri); 1.314 - } catch (ClientProtocolException e) { 1.315 - if (context != null) { 1.316 - NotificationsHelper.signalSyncErrors(context, "Caldav sync problem", e.getMessage()); 1.317 - //NotificationsHelper.getCurrentSyncLog().addException(e); 1.318 - } 1.319 - exception = e; 1.320 - } catch (FileNotFoundException e) { 1.321 - if (context != null) { 1.322 - NotificationsHelper.signalSyncErrors(context, "Caldav sync problem", e.getMessage()); 1.323 - //NotificationsHelper.getCurrentSyncLog().addException(e); 1.324 - } 1.325 - throw e; 1.326 - } catch (IOException e) { 1.327 - if (context != null) { 1.328 - NotificationsHelper.signalSyncErrors(context, "Caldav sync problem", e.getMessage()); 1.329 - //NotificationsHelper.getCurrentSyncLog().addException(e); 1.330 - } 1.331 - exception = e; 1.332 - } catch (CaldavProtocolException e) { 1.333 + //http://dlinsin.blogspot.de/2009/08/http-basic-authentication-with-android.html 1.334 + ((AbstractHttpClient) httpClient).addRequestInterceptor(preemptiveAuth, 0); 1.335 1.336 - if (context != null) { 1.337 - NotificationsHelper.signalSyncErrors(context, "Caldav sync problem", e.getMessage()); 1.338 - //NotificationsHelper.getCurrentSyncLog().addException(e); 1.339 - } 1.340 - exception = e; 1.341 - } 1.342 - if (exception != null && BuildConfig.DEBUG) { 1.343 - Log.e(TAG, "Force get calendars from '" + uri.toString() 1.344 - + "' failed " + exception.getClass().getCanonicalName() 1.345 - + ": " + exception.getMessage()); 1.346 - } 1.347 - return calendars; 1.348 - } 1.349 + String proto = "http"; 1.350 + int port = 80; 1.351 1.352 - private final static String PROPFIND_USER_PRINCIPAL = XML_VERSION + 1.353 - "<d:propfind xmlns:d=\"DAV:\">" + 1.354 - "<d:prop>" + 1.355 - "<d:current-user-principal />" + 1.356 - "<d:principal-URL />" + 1.357 - "</d:prop>" + 1.358 - "</d:propfind>"; 1.359 - 1.360 - private URI getUserPrincipal() throws SocketException, 1.361 - ClientProtocolException, AuthenticationException, 1.362 - FileNotFoundException, IOException, CaldavProtocolException, 1.363 - URISyntaxException { 1.364 - URI uri = this.url.toURI(); 1.365 - HttpPropFind request = createPropFindRequest(uri, 1.366 - PROPFIND_USER_PRINCIPAL, 0); 1.367 - HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.368 - checkStatus(response); 1.369 - ServerInfoHandler serverInfoHandler = new ServerInfoHandler(); 1.370 - parseXML(response, serverInfoHandler); 1.371 - String userPrincipal = null; 1.372 - if (serverInfoHandler.currentUserPrincipal != null) { 1.373 - userPrincipal = serverInfoHandler.currentUserPrincipal; 1.374 - } else if (serverInfoHandler.principalUrl != null) { 1.375 - userPrincipal = serverInfoHandler.principalUrl; 1.376 - } else { 1.377 - throw new CaldavProtocolException("no principal url found"); 1.378 - } 1.379 - try { 1.380 - URI userPrincipalUri = new URI(userPrincipal); 1.381 - userPrincipalUri = uri.resolve(userPrincipalUri); 1.382 - if (BuildConfig.DEBUG) { 1.383 - Log.d(TAG, 1.384 - "Found userPrincipal: " + userPrincipalUri.toString()); 1.385 - } 1.386 - return userPrincipalUri; 1.387 - } catch (URISyntaxException e) { 1.388 - throw new CaldavProtocolException("principal url '" + userPrincipal 1.389 - + "' malformed"); 1.390 - } 1.391 - } 1.392 + if (url.getProtocol().equalsIgnoreCase("https")) { 1.393 + proto = "https"; 1.394 + if (url.getPort() == -1) 1.395 + port = 443; 1.396 + else 1.397 + port = url.getPort(); 1.398 + } 1.399 1.400 - private final static String PROPFIND_CALENDAR_HOME_SET = XML_VERSION 1.401 - + "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\"><d:prop><c:calendar-home-set/></d:prop></d:propfind>"; 1.402 + if (url.getProtocol().equalsIgnoreCase("http")) { 1.403 + proto = "http"; 1.404 + if (url.getPort() == -1) 1.405 + port = 80; 1.406 + else 1.407 + port = url.getPort(); 1.408 + } 1.409 + targetHost = new HttpHost(url.getHost(), port, proto); 1.410 + } 1.411 1.412 - private List<URI> getCalendarHomes(URI userPrincipal) 1.413 - throws ClientProtocolException, IOException, 1.414 - AuthenticationException, FileNotFoundException, 1.415 - CaldavProtocolException { 1.416 - HttpPropFind request = createPropFindRequest(userPrincipal, 1.417 - PROPFIND_CALENDAR_HOME_SET, 0); 1.418 - HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.419 - checkStatus(response); 1.420 - CalendarHomeHandler calendarHomeHandler = new CalendarHomeHandler( 1.421 - userPrincipal); 1.422 - parseXML(response, calendarHomeHandler); 1.423 - List<URI> result = calendarHomeHandler.calendarHomeSet; 1.424 - if (BuildConfig.DEBUG) { 1.425 - Log.d(TAG, result.size() + " calendar-home-set found in " 1.426 - + userPrincipal.toString()); 1.427 - } 1.428 - return result; 1.429 - } 1.430 + //http://dlinsin.blogspot.de/2009/08/http-basic-authentication-with-android.html 1.431 + HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() { 1.432 + @Override 1.433 + public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { 1.434 + AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); 1.435 1.436 - private final static String PROPFIND_CALENDER_LIST = XML_VERSION 1.437 - + "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\" xmlns:ic=\"http://apple.com/ns/ical/\">" 1.438 - + "<d:prop><d:displayname /><d:resourcetype />" 1.439 - // + 1.440 - // "<d:supported-method-set /><d:supported-report-set /><c:supported-calendar-component-set />" 1.441 - // + 1.442 - // "<c:calendar-description /><c:calendar-timezone /><c:calendar-free-busy-set /> 1.443 - + "<ic:calendar-color />" 1.444 - //<ic:calendar-order />" 1.445 - + "<cs:getctag /></d:prop></d:propfind>"; 1.446 + if (authState.getAuthScheme() == null) { 1.447 + if (mLastAuthState != null) { 1.448 + Log.d(TAG, "LastAuthState: restored with user " + mLastAuthState.getCredentials() 1.449 + .getUserPrincipal() 1.450 + .getName()); 1.451 + authState.setAuthScheme(mLastAuthState.getAuthScheme()); 1.452 + authState.setCredentials(mLastAuthState.getCredentials()); 1.453 + } else { 1.454 + Log.d(TAG, "LastAuthState: nothing to do"); 1.455 + } 1.456 + if (mLastAuthScope != null) { 1.457 + authState.setAuthScope(mLastAuthScope); 1.458 + Log.d(TAG, "LastAuthScope: restored"); 1.459 + } else { 1.460 + Log.d(TAG, "LastAuthScope: nothing to do"); 1.461 + } 1.462 + } else { 1.463 + //AuthState and AuthScope have to be saved separate because of the AuthScope within AuthState gets lost, so we save it in a separate var. 1.464 + mLastAuthState = authState; 1.465 + Log.d(TAG, "LastAuthState: new with user " + mLastAuthState.getCredentials() 1.466 + .getUserPrincipal() 1.467 + .getName()); 1.468 + if (authState.getAuthScope() != null) { 1.469 + mLastAuthScope = authState.getAuthScope(); 1.470 + Log.d(TAG, "LastAuthScope: new"); 1.471 + } 1.472 + } 1.473 + } 1.474 + }; 1.475 1.476 - 1.477 - private List<DavCalendar> getCalendarsFromSet(URI calendarSet) 1.478 - throws ClientProtocolException, IOException, 1.479 - CaldavProtocolException, AuthenticationException, 1.480 - FileNotFoundException { 1.481 - HttpPropFind request = createPropFindRequest(calendarSet, PROPFIND_CALENDER_LIST, 1); 1.482 - HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.483 - checkStatus(response); 1.484 - CalendarsHandler calendarsHandler = new CalendarsHandler(calendarSet); 1.485 - parseXML(response, calendarsHandler); 1.486 - List<DavCalendar> result = calendarsHandler.calendars; 1.487 - if (BuildConfig.DEBUG) { 1.488 - Log.i(TAG, 1.489 - result.size() + " calendars found in set " 1.490 - + calendarSet.toString()); 1.491 - } 1.492 - return result; 1.493 - } 1.494 - 1.495 - /** 1.496 - * Discover CalDAV Calendars Mentioned in 1.497 - * http://tools.ietf.org/html/draft-daboo-srv-caldav-10#section-6 and 1.498 - * http://code.google.com/p/sabredav/wiki/BuildingACalDAVClient#Discovery 1.499 - * <ol> 1.500 - * <li>PROPFIND calendar-home-set on url 1.501 - * <li>PROPFIND DAV:current-user-principal or principal-URL on url 1.502 - * <li>PROPFIND calendar-home-set on current-user-principal or principal-URL 1.503 - * <li>PROPFIND displayname, resourcetype, getctag on CalendarHomeSets 1.504 - * </ol> 1.505 - * @param context 1.506 - * 1.507 - * @return List of {@link DavCalendar} 1.508 - * @throws ClientProtocolException 1.509 - * http protocol error 1.510 - * @throws IOException 1.511 - * Connection lost 1.512 - * @throws URISyntaxException 1.513 - * url in Constructor malformed 1.514 - * @throws CaldavProtocolException 1.515 - * caldav protocol error 1.516 - */ 1.517 - //public Iterable<Calendar> getCalendarList(Context context) throws ClientProtocolException, 1.518 - public CalendarList getCalendarList(Context context) throws ClientProtocolException, 1.519 - IOException, URISyntaxException, ParserConfigurationException, 1.520 - CaldavProtocolException { 1.521 - try { 1.522 - CalendarList Result = new CalendarList(this.mAccount, this.mProvider, CalendarSource.CalDAV, this.url.toString()); 1.523 - List<DavCalendar> calendars = new ArrayList<DavCalendar>(); 1.524 - 1.525 - calendars = forceGetCalendarsFromUri(context, this.url.toURI()); 1.526 - 1.527 - if (calendars.size() == 0) { 1.528 - // no calendars found, try the home-set 1.529 - URI userPrincipal = getUserPrincipal(); 1.530 - List<URI> calendarSets = getCalendarHomes(userPrincipal); 1.531 - for (URI calendarSet : calendarSets) { 1.532 - List<DavCalendar> calendarSetCalendars = getCalendarsFromSet(calendarSet); 1.533 - calendars.addAll(calendarSetCalendars); 1.534 - } 1.535 - } 1.536 - for (DavCalendar cal : calendars) { 1.537 - Result.addCalendar(cal); 1.538 - } 1.539 - 1.540 - //return calendars; 1.541 - return Result; 1.542 - } catch (AuthenticationException e) { 1.543 - throw new IOException(e); 1.544 - } 1.545 - } 1.546 + public enum TestConnectionResult { 1.547 + WRONG_CREDENTIAL, 1.548 + WRONG_URL, 1.549 + WRONG_SERVER_STATUS, 1.550 + WRONG_ANSWER, 1.551 + SSL_ERROR, 1.552 + SUCCESS 1.553 + } 1.554 1.555 - //public Iterable<CalendarEvent> getCalendarEvents(DavCalendar calendar) 1.556 - public ArrayList<CalendarEvent> getCalendarEvents(DavCalendar calendar) 1.557 - throws URISyntaxException, ClientProtocolException, IOException, 1.558 - ParserConfigurationException, SAXException { 1.559 + /** 1.560 + * TODO: testConnection should return only an instance of 1.561 + * TestConnectionResult without throwing an exception or only throw checked 1.562 + * exceptions so you don't have to check the result of this function AND 1.563 + * handle the exceptions 1.564 + * 1.565 + * @return {@link TestConnectionResult} 1.566 + * @throws HttpHostConnectException 1.567 + * @throws IOException 1.568 + * @throws URISyntaxException 1.569 + * @throws ParserConfigurationException 1.570 + * @throws SAXException 1.571 + */ 1.572 + public TestConnectionResult testConnection() throws IOException, URISyntaxException, ParserConfigurationException, SAXException { 1.573 + Log.d(TAG, "start testConnection "); 1.574 + try { 1.575 + List<DavCalendar> calendars = new ArrayList<DavCalendar>(); 1.576 + calendars = forceGetCalendarsFromUri(null, url.toURI()); 1.577 + if (calendars.size() != 0) { 1.578 + return TestConnectionResult.SUCCESS; 1.579 + } 1.580 1.581 - ArrayList<CalendarEvent> calendarEventList = new ArrayList<CalendarEvent>(); 1.582 + URI userPrincipal = getUserPrincipal(); 1.583 + List<URI> calendarSets = getCalendarHomes(userPrincipal); 1.584 + for (URI calendarSet : calendarSets) { 1.585 + List<DavCalendar> calendarSetCalendars = getCalendarsFromSet(calendarSet); 1.586 + calendars.addAll(calendarSetCalendars); 1.587 + } 1.588 + if (calendarSets.size() == 0) { 1.589 + return TestConnectionResult.WRONG_ANSWER; 1.590 + } 1.591 + } catch (FileNotFoundException e) { 1.592 + return TestConnectionResult.WRONG_URL; 1.593 + } catch (SSLException e) { 1.594 + return TestConnectionResult.SSL_ERROR; 1.595 + } catch (SocketException e) { 1.596 + return TestConnectionResult.WRONG_URL; 1.597 + } catch (AuthenticationException e) { 1.598 + return TestConnectionResult.WRONG_CREDENTIAL; 1.599 + } catch (ClientProtocolException e) { 1.600 + return TestConnectionResult.WRONG_SERVER_STATUS; 1.601 + } catch (CaldavProtocolException e) { 1.602 + return TestConnectionResult.WRONG_ANSWER; 1.603 + } 1.604 + return TestConnectionResult.SUCCESS; 1.605 + } 1.606 1.607 - String requestBody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 1.608 - + "<D:propfind xmlns:D=\"DAV:\">" + "<D:prop>" + "<D:getetag/>" 1.609 - + "</D:prop>" + "</D:propfind>"; 1.610 + /** 1.611 + * @param context May be null if no notification is needed 1.612 + * @param uri 1.613 + * @return 1.614 + * @throws AuthenticationException 1.615 + * @throws FileNotFoundException 1.616 + */ 1.617 + private List<DavCalendar> forceGetCalendarsFromUri(Context context, URI uri) throws AuthenticationException, FileNotFoundException { 1.618 + List<DavCalendar> calendars = new ArrayList<DavCalendar>(); 1.619 + Exception exception = null; 1.620 + try { 1.621 + calendars = getCalendarsFromSet(uri); 1.622 + } catch (ClientProtocolException e) { 1.623 + if (context != null) { 1.624 + NotificationsHelper.signalSyncErrors(context, "Caldav sync problem", e.getMessage()); 1.625 + //NotificationsHelper.getCurrentSyncLog().addException(e); 1.626 + } 1.627 + exception = e; 1.628 + } catch (FileNotFoundException e) { 1.629 + if (context != null) { 1.630 + NotificationsHelper.signalSyncErrors(context, "Caldav sync problem", e.getMessage()); 1.631 + //NotificationsHelper.getCurrentSyncLog().addException(e); 1.632 + } 1.633 + throw e; 1.634 + } catch (IOException e) { 1.635 + if (context != null) { 1.636 + NotificationsHelper.signalSyncErrors(context, "Caldav sync problem", e.getMessage()); 1.637 + //NotificationsHelper.getCurrentSyncLog().addException(e); 1.638 + } 1.639 + exception = e; 1.640 + } catch (CaldavProtocolException e) { 1.641 1.642 - HttpPropFind request = null; 1.643 - 1.644 - String EventUri; 1.645 + if (context != null) { 1.646 + NotificationsHelper.signalSyncErrors(context, "Caldav sync problem", e.getMessage()); 1.647 + //NotificationsHelper.getCurrentSyncLog().addException(e); 1.648 + } 1.649 + exception = e; 1.650 + } 1.651 + if (exception != null && BuildConfig.DEBUG) { 1.652 + Log.e(TAG, "Force get calendars from '" + uri.toString() 1.653 + + "' failed " + exception.getClass().getCanonicalName() 1.654 + + ": " + exception.getMessage()); 1.655 + } 1.656 + return calendars; 1.657 + } 1.658 + 1.659 + private final static String PROPFIND_USER_PRINCIPAL = XML_VERSION + 1.660 + "<d:propfind xmlns:d=\"DAV:\">" + 1.661 + "<d:prop>" + 1.662 + "<d:current-user-principal />" + 1.663 + "<d:principal-URL />" + 1.664 + "</d:prop>" + 1.665 + "</d:propfind>"; 1.666 + 1.667 + private URI getUserPrincipal() throws 1.668 + AuthenticationException, 1.669 + IOException, CaldavProtocolException, 1.670 + URISyntaxException { 1.671 + URI uri = this.url.toURI(); 1.672 + HttpPropFind request = createPropFindRequest(uri, 1.673 + PROPFIND_USER_PRINCIPAL, 0); 1.674 + HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.675 + checkStatus(response); 1.676 + ServerInfoHandler serverInfoHandler = new ServerInfoHandler(); 1.677 + parseXML(response, serverInfoHandler); 1.678 + String userPrincipal = null; 1.679 + if (serverInfoHandler.currentUserPrincipal != null) { 1.680 + userPrincipal = serverInfoHandler.currentUserPrincipal; 1.681 + } else if (serverInfoHandler.principalUrl != null) { 1.682 + userPrincipal = serverInfoHandler.principalUrl; 1.683 + } else { 1.684 + throw new CaldavProtocolException("no principal url found"); 1.685 + } 1.686 + try { 1.687 + URI userPrincipalUri = new URI(userPrincipal); 1.688 + userPrincipalUri = uri.resolve(userPrincipalUri); 1.689 + if (BuildConfig.DEBUG) { 1.690 + Log.d(TAG, 1.691 + "Found userPrincipal: " + userPrincipalUri.toString()); 1.692 + } 1.693 + return userPrincipalUri; 1.694 + } catch (URISyntaxException e) { 1.695 + throw new CaldavProtocolException("principal url '" + userPrincipal 1.696 + + "' malformed"); 1.697 + } 1.698 + } 1.699 + 1.700 + private final static String PROPFIND_CALENDAR_HOME_SET = XML_VERSION 1.701 + + "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\"><d:prop><c:calendar-home-set/></d:prop></d:propfind>"; 1.702 + 1.703 + private List<URI> getCalendarHomes(URI userPrincipal) 1.704 + throws ClientProtocolException, IOException, 1.705 + AuthenticationException, FileNotFoundException, 1.706 + CaldavProtocolException { 1.707 + HttpPropFind request = createPropFindRequest(userPrincipal, 1.708 + PROPFIND_CALENDAR_HOME_SET, 0); 1.709 + HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.710 + checkStatus(response); 1.711 + CalendarHomeHandler calendarHomeHandler = new CalendarHomeHandler( 1.712 + userPrincipal); 1.713 + parseXML(response, calendarHomeHandler); 1.714 + List<URI> result = calendarHomeHandler.calendarHomeSet; 1.715 + if (BuildConfig.DEBUG) { 1.716 + Log.d(TAG, result.size() + " calendar-home-set found in " 1.717 + + userPrincipal.toString()); 1.718 + } 1.719 + return result; 1.720 + } 1.721 + 1.722 + private final static String PROPFIND_CALENDER_LIST = XML_VERSION 1.723 + + "<d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\" xmlns:ic=\"http://apple.com/ns/ical/\">" 1.724 + + "<d:prop><d:displayname /><d:resourcetype />" 1.725 + // + 1.726 + // "<d:supported-method-set /><d:supported-report-set /><c:supported-calendar-component-set />" 1.727 + // + 1.728 + // "<c:calendar-description /><c:calendar-timezone /><c:calendar-free-busy-set /> 1.729 + + "<ic:calendar-color />" 1.730 + //<ic:calendar-order />" 1.731 + + "<cs:getctag /></d:prop></d:propfind>"; 1.732 + 1.733 + 1.734 + private List<DavCalendar> getCalendarsFromSet(URI calendarSet) 1.735 + throws ClientProtocolException, IOException, 1.736 + CaldavProtocolException, AuthenticationException, 1.737 + FileNotFoundException { 1.738 + HttpPropFind request = createPropFindRequest(calendarSet, PROPFIND_CALENDER_LIST, 1); 1.739 + HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.740 + checkStatus(response); 1.741 + CalendarsHandler calendarsHandler = new CalendarsHandler(calendarSet); 1.742 + parseXML(response, calendarsHandler); 1.743 + List<DavCalendar> result = calendarsHandler.calendars; 1.744 + if (BuildConfig.DEBUG) { 1.745 + Log.i(TAG, 1.746 + result.size() + " calendars found in set " 1.747 + + calendarSet.toString() 1.748 + ); 1.749 + } 1.750 + return result; 1.751 + } 1.752 + 1.753 + /** 1.754 + * Discover CalDAV Calendars Mentioned in 1.755 + * http://tools.ietf.org/html/draft-daboo-srv-caldav-10#section-6 and 1.756 + * http://code.google.com/p/sabredav/wiki/BuildingACalDAVClient#Discovery 1.757 + * <ol> 1.758 + * <li>PROPFIND calendar-home-set on url 1.759 + * <li>PROPFIND DAV:current-user-principal or principal-URL on url 1.760 + * <li>PROPFIND calendar-home-set on current-user-principal or principal-URL 1.761 + * <li>PROPFIND displayname, resourcetype, getctag on CalendarHomeSets 1.762 + * </ol> 1.763 + * 1.764 + * @param context 1.765 + * @return List of {@link DavCalendar} 1.766 + * @throws ClientProtocolException http protocol error 1.767 + * @throws IOException Connection lost 1.768 + * @throws URISyntaxException url in Constructor malformed 1.769 + * @throws CaldavProtocolException caldav protocol error 1.770 + */ 1.771 + //public Iterable<Calendar> getCalendarList(Context context) throws ClientProtocolException, 1.772 + public CalendarList getCalendarList(Context context) throws ClientProtocolException, 1.773 + IOException, URISyntaxException, ParserConfigurationException, 1.774 + CaldavProtocolException { 1.775 + try { 1.776 + CalendarList Result = new CalendarList(this.mAccount, this.mProvider, CalendarSource.CalDAV, this.url 1.777 + .toString()); 1.778 + List<DavCalendar> calendars = new ArrayList<DavCalendar>(); 1.779 + 1.780 + calendars = forceGetCalendarsFromUri(context, this.url.toURI()); 1.781 + 1.782 + if (calendars.size() == 0) { 1.783 + // no calendars found, try the home-set 1.784 + URI userPrincipal = getUserPrincipal(); 1.785 + List<URI> calendarSets = getCalendarHomes(userPrincipal); 1.786 + for (URI calendarSet : calendarSets) { 1.787 + List<DavCalendar> calendarSetCalendars = getCalendarsFromSet(calendarSet); 1.788 + calendars.addAll(calendarSetCalendars); 1.789 + } 1.790 + } 1.791 + for (DavCalendar cal : calendars) { 1.792 + Result.addCalendar(cal); 1.793 + } 1.794 + 1.795 + //return calendars; 1.796 + return Result; 1.797 + } catch (AuthenticationException e) { 1.798 + throw new IOException(e); 1.799 + } 1.800 + } 1.801 + 1.802 + //public Iterable<CalendarEvent> getCalendarEvents(DavCalendar calendar) 1.803 + public ArrayList<CalendarEvent> getCalendarEvents(DavCalendar calendar) 1.804 + throws URISyntaxException, ClientProtocolException, IOException, 1.805 + ParserConfigurationException, SAXException { 1.806 + 1.807 + ArrayList<CalendarEvent> calendarEventList = new ArrayList<CalendarEvent>(); 1.808 + 1.809 + String requestBody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 1.810 + + "<D:propfind xmlns:D=\"DAV:\">" + "<D:prop>" + "<D:getetag/>" 1.811 + + "</D:prop>" + "</D:propfind>"; 1.812 + 1.813 + HttpPropFind request = null; 1.814 + 1.815 + String EventUri; 1.816 1.817 /*request = new HttpPropFind(); 1.818 - request.setURI(calendar.getURI()); 1.819 + request.setURI(calendar.getURI()); 1.820 request.setHeader("Host", targetHost.getHostName()); 1.821 request.setHeader("Depth", "1"); 1.822 request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.823 @@ -487,380 +494,358 @@ 1.824 } catch (UnsupportedEncodingException e) { 1.825 throw new AssertionError("UTF-8 is unknown"); 1.826 }*/ 1.827 - request = this.createPropFindRequest(calendar.getURI(), requestBody, 1); 1.828 - 1.829 - Log.d(TAG, "Getting eTag by PROPFIND at " + request.getURI()); 1.830 + request = this.createPropFindRequest(calendar.getURI(), requestBody, 1); 1.831 1.832 - HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.833 + Log.d(TAG, "Getting eTag by PROPFIND at " + request.getURI()); 1.834 1.835 - BufferedReader reader = new BufferedReader(new InputStreamReader( 1.836 - response.getEntity().getContent(), "UTF-8")); 1.837 + HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.838 + String body = EntityUtils.toString(response.getEntity(), "UTF-8"); 1.839 1.840 - String line; 1.841 - String body = ""; 1.842 - do { 1.843 - line = reader.readLine(); 1.844 - if (line != null) 1.845 - body += line; 1.846 - } while (line != null); 1.847 + Log.d(TAG, "HttpResponse status=" + response.getStatusLine() 1.848 + + " body= " + body); 1.849 1.850 - Log.d(TAG, "HttpResponse status=" + response.getStatusLine() 1.851 - + " body= " + body); 1.852 + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 1.853 + factory.setNamespaceAware(true); 1.854 + DocumentBuilder builder = factory.newDocumentBuilder(); 1.855 + Document dom = builder.parse(new InputSource(new ByteArrayInputStream( 1.856 + body.getBytes("utf-8")))); 1.857 + Element root = dom.getDocumentElement(); 1.858 + NodeList items = root.getElementsByTagNameNS("*", "getetag"); 1.859 1.860 - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 1.861 - factory.setNamespaceAware(true); 1.862 - DocumentBuilder builder = factory.newDocumentBuilder(); 1.863 - Document dom = builder.parse(new InputSource(new ByteArrayInputStream( 1.864 - body.getBytes("utf-8")))); 1.865 - Element root = dom.getDocumentElement(); 1.866 - NodeList items = root.getElementsByTagNameNS("*", "getetag"); 1.867 + for (int i = 0; i < items.getLength(); i++) { 1.868 + CalendarEvent calendarEvent = new CalendarEvent(this.mAccount, this.mProvider); 1.869 1.870 - for (int i = 0; i < items.getLength(); i++) { 1.871 - CalendarEvent calendarEvent = new CalendarEvent(this.mAccount, this.mProvider); 1.872 + Node node = items.item(i); 1.873 1.874 - Node node = items.item(i); 1.875 + if (node.getTextContent().trim().length() == 0) 1.876 + continue; // not an event 1.877 1.878 - if (node.getTextContent().trim().length() == 0) 1.879 - continue; // not an event 1.880 + calendarEvent.setETag(node.getTextContent().trim()); 1.881 + //calendarEvent.calendarURL = this.url; 1.882 + calendarEvent.calendarURL = calendar.getURI().toURL(); 1.883 1.884 - calendarEvent.setETag(node.getTextContent().trim()); 1.885 - //calendarEvent.calendarURL = this.url; 1.886 - calendarEvent.calendarURL = calendar.getURI().toURL(); 1.887 + node = node.getParentNode(); // prop 1.888 + node = node.getParentNode(); // propstat 1.889 + node = node.getParentNode(); // response 1.890 1.891 - node = node.getParentNode(); // prop 1.892 - node = node.getParentNode(); // propstat 1.893 - node = node.getParentNode(); // response 1.894 + NodeList children = node.getChildNodes(); 1.895 + for (int j = 0; j < children.getLength(); j++) { 1.896 + Node childNode = children.item(j); 1.897 + if ((childNode.getLocalName() != null) && (childNode.getLocalName() 1.898 + .equalsIgnoreCase("href"))) { 1.899 + EventUri = childNode.getTextContent().trim(); 1.900 + //HINT: bugfix for zimbra calendar: replace("@", "%40") 1.901 + EventUri = EventUri.replace("@", "%40"); 1.902 + calendarEvent.setUri(new URI(EventUri)); 1.903 + } 1.904 + } 1.905 1.906 - NodeList children = node.getChildNodes(); 1.907 - for (int j = 0; j < children.getLength(); j++) { 1.908 - Node childNode = children.item(j); 1.909 - if ((childNode.getLocalName()!=null) && (childNode.getLocalName().equalsIgnoreCase("href"))) { 1.910 - EventUri = childNode.getTextContent().trim(); 1.911 - //HINT: bugfix for zimbra calendar: replace("@", "%40") 1.912 - EventUri = EventUri.replace("@", "%40"); 1.913 - calendarEvent.setUri(new URI(EventUri)); 1.914 - } 1.915 - } 1.916 + calendarEventList.add(calendarEvent); 1.917 1.918 - calendarEventList.add(calendarEvent); 1.919 + } 1.920 1.921 - } 1.922 + return calendarEventList; 1.923 + } 1.924 1.925 - return calendarEventList; 1.926 - } 1.927 - 1.928 - private void parseXML(HttpResponse response, ContentHandler contentHandler) 1.929 - throws IOException, CaldavProtocolException { 1.930 - InputStream is = response.getEntity().getContent(); 1.931 - /*BufferedReader bReader = new BufferedReader(new InputStreamReader(is, "UTF-8")); 1.932 - String Content = ""; 1.933 + private void parseXML(HttpResponse response, ContentHandler contentHandler) 1.934 + throws IOException, CaldavProtocolException { 1.935 + InputStream is = response.getEntity().getContent(); 1.936 + /*BufferedReader bReader = new BufferedReader(new InputStreamReader(is, "UTF-8")); 1.937 + String Content = ""; 1.938 String Line = bReader.readLine(); 1.939 1.940 while (Line != null) { 1.941 Content += Line; 1.942 Line = bReader.readLine(); 1.943 }*/ 1.944 - 1.945 - SAXParserFactory factory = SAXParserFactory.newInstance(); 1.946 - try { 1.947 - SAXParser parser = factory.newSAXParser(); 1.948 - XMLReader reader = parser.getXMLReader(); 1.949 - reader.setContentHandler(contentHandler); 1.950 - reader.parse(new InputSource(is)); 1.951 - } catch (ParserConfigurationException e) { 1.952 - throw new AssertionError("ParserConfigurationException " 1.953 - + e.getMessage()); 1.954 - } catch (IllegalStateException e) { 1.955 - throw new CaldavProtocolException(e.getMessage()); 1.956 - } catch (SAXException e) { 1.957 - throw new CaldavProtocolException(e.getMessage()); 1.958 - } 1.959 - } 1.960 1.961 - private void checkStatus(HttpResponse response) 1.962 - throws AuthenticationException, FileNotFoundException, 1.963 - ClientProtocolException { 1.964 - final int statusCode = response.getStatusLine().getStatusCode(); 1.965 - lastStatusCode = statusCode; 1.966 - if (response.containsHeader("ETag")) 1.967 - lastETag = response.getFirstHeader("ETag").getValue(); 1.968 - else 1.969 - lastETag = ""; 1.970 - if (response.containsHeader("DAV")) 1.971 - lastDav = response.getFirstHeader("DAV").getValue(); 1.972 - else 1.973 - lastDav = ""; 1.974 - 1.975 - switch (statusCode) { 1.976 - case 401: 1.977 - throw new AuthenticationException(); 1.978 - case 404: 1.979 - throw new FileNotFoundException(); 1.980 - case 409: //Conflict 1.981 - case 412: 1.982 - case 200: 1.983 - case 201: 1.984 - case 204: 1.985 - case 207: 1.986 - return; 1.987 - default: 1.988 - throw new ClientProtocolException("StatusCode: " + statusCode); 1.989 - } 1.990 - } 1.991 + SAXParserFactory factory = SAXParserFactory.newInstance(); 1.992 + try { 1.993 + SAXParser parser = factory.newSAXParser(); 1.994 + XMLReader reader = parser.getXMLReader(); 1.995 + reader.setContentHandler(contentHandler); 1.996 + reader.parse(new InputSource(is)); 1.997 + } catch (ParserConfigurationException e) { 1.998 + throw new AssertionError("ParserConfigurationException " 1.999 + + e.getMessage()); 1.1000 + } catch (IllegalStateException e) { 1.1001 + throw new CaldavProtocolException(e.getMessage()); 1.1002 + } catch (SAXException e) { 1.1003 + throw new CaldavProtocolException(e.getMessage()); 1.1004 + } 1.1005 + } 1.1006 1.1007 - private HttpPropFind createPropFindRequest(URI uri, String data, int depth) { 1.1008 - HttpPropFind request = new HttpPropFind(); 1.1009 + private void checkStatus(HttpResponse response) 1.1010 + throws AuthenticationException, FileNotFoundException, 1.1011 + ClientProtocolException { 1.1012 + final int statusCode = response.getStatusLine().getStatusCode(); 1.1013 + lastStatusCode = statusCode; 1.1014 + if (response.containsHeader("ETag")) 1.1015 + lastETag = response.getFirstHeader("ETag").getValue(); 1.1016 + else 1.1017 + lastETag = ""; 1.1018 + if (response.containsHeader("DAV")) 1.1019 + lastDav = response.getFirstHeader("DAV").getValue(); 1.1020 + else 1.1021 + lastDav = ""; 1.1022 1.1023 - request.setURI(uri); 1.1024 - //request.setHeader("Host", targetHost.getHostName()); 1.1025 - request.setHeader("Host", targetHost.getHostName() + ":" + String.valueOf(targetHost.getPort())); 1.1026 - request.setHeader("Depth", Integer.toString(depth)); 1.1027 - request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1028 - try { 1.1029 - request.setEntity(new StringEntity(data, "UTF-8")); 1.1030 - } catch (UnsupportedEncodingException e) { 1.1031 - throw new AssertionError("UTF-8 is unknown"); 1.1032 - } 1.1033 - return request; 1.1034 - } 1.1035 - 1.1036 - private HttpDelete createDeleteRequest(URI uri) { 1.1037 - HttpDelete request = new HttpDelete(); 1.1038 - request.setURI(uri); 1.1039 - //request.setHeader("Host", targetHost.getHostName()); 1.1040 - request.setHeader("Host", targetHost.getHostName() + ":" + String.valueOf(targetHost.getPort())); 1.1041 - request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1042 - return request; 1.1043 - } 1.1044 + switch (statusCode) { 1.1045 + case 401: 1.1046 + throw new AuthenticationException(); 1.1047 + case 404: 1.1048 + throw new FileNotFoundException(); 1.1049 + case 409: //Conflict 1.1050 + case 412: 1.1051 + case 200: 1.1052 + case 201: 1.1053 + case 204: 1.1054 + case 207: 1.1055 + return; 1.1056 + default: 1.1057 + throw new ClientProtocolException("StatusCode: " + statusCode); 1.1058 + } 1.1059 + } 1.1060 1.1061 - private HttpPut createPutRequest(URI uri, String data, int depth) { 1.1062 - HttpPut request = new HttpPut(); 1.1063 - request.setURI(uri); 1.1064 - //request.setHeader("Host", targetHost.getHostName()); 1.1065 - request.setHeader("Host", targetHost.getHostName() + ":" + String.valueOf(targetHost.getPort())); 1.1066 - //request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1067 - request.setHeader("Content-Type", "text/calendar; charset=UTF-8"); 1.1068 - try { 1.1069 - request.setEntity(new StringEntity(data, "UTF-8")); 1.1070 - //request.setEntity(new StringEntity(data)); 1.1071 - } catch (UnsupportedEncodingException e) { 1.1072 - throw new AssertionError("UTF-8 is unknown"); 1.1073 - } 1.1074 - return request; 1.1075 - } 1.1076 - 1.1077 - private static HttpReport createReportRequest(URI uri, String data, int depth) { 1.1078 - HttpReport request = new HttpReport(); 1.1079 - request.setURI(uri); 1.1080 - //request.setHeader("Host", targetHost.getHostName()); 1.1081 - request.setHeader("Host", targetHost.getHostName() + ":" + String.valueOf(targetHost.getPort())); 1.1082 - request.setHeader("Depth", Integer.toString(depth)); 1.1083 - request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1084 - //request.setHeader("Content-Type", "text/xml;charset=\"UTF-8\""); 1.1085 - try { 1.1086 - request.setEntity(new StringEntity(data)); 1.1087 - } catch (UnsupportedEncodingException e) { 1.1088 - throw new AssertionError("UTF-8 is unknown"); 1.1089 - } 1.1090 - return request; 1.1091 - } 1.1092 - 1.1093 - public static void fetchEvent_old(CalendarEvent calendarEvent) 1.1094 - throws ClientProtocolException, IOException { 1.1095 - HttpGet request = null; 1.1096 + private HttpPropFind createPropFindRequest(URI uri, String data, int depth) { 1.1097 + HttpPropFind request = new HttpPropFind(); 1.1098 1.1099 - request = new HttpGet(); 1.1100 - request.setURI(calendarEvent.getUri()); 1.1101 - request.setHeader("Host", targetHost.getHostName()); 1.1102 - request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1103 + request.setURI(uri); 1.1104 + //request.setHeader("Host", targetHost.getHostName()); 1.1105 + request.setHeader("Host", targetHost.getHostName() + ":" + String.valueOf(targetHost.getPort())); 1.1106 + request.setHeader("Depth", Integer.toString(depth)); 1.1107 + request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1108 + try { 1.1109 + request.setEntity(new StringEntity(data, "UTF-8")); 1.1110 + } catch (UnsupportedEncodingException e) { 1.1111 + throw new AssertionError("UTF-8 is unknown"); 1.1112 + } 1.1113 + return request; 1.1114 + } 1.1115 1.1116 - HttpResponse response = httpClient.execute(targetHost, request); 1.1117 + private HttpDelete createDeleteRequest(URI uri) { 1.1118 + HttpDelete request = new HttpDelete(); 1.1119 + request.setURI(uri); 1.1120 + //request.setHeader("Host", targetHost.getHostName()); 1.1121 + request.setHeader("Host", targetHost.getHostName() + ":" + String.valueOf(targetHost.getPort())); 1.1122 + request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1123 + return request; 1.1124 + } 1.1125 1.1126 - BufferedReader reader = new BufferedReader(new InputStreamReader( 1.1127 - response.getEntity().getContent(), "UTF-8")); 1.1128 + private HttpPut createPutRequest(URI uri, String data, int depth) { 1.1129 + HttpPut request = new HttpPut(); 1.1130 + request.setURI(uri); 1.1131 + //request.setHeader("Host", targetHost.getHostName()); 1.1132 + request.setHeader("Host", targetHost.getHostName() + ":" + String.valueOf(targetHost.getPort())); 1.1133 + //request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1134 + request.setHeader("Content-Type", "text/calendar; charset=UTF-8"); 1.1135 + try { 1.1136 + request.setEntity(new StringEntity(data, "UTF-8")); 1.1137 + //request.setEntity(new StringEntity(data)); 1.1138 + } catch (UnsupportedEncodingException e) { 1.1139 + throw new AssertionError("UTF-8 is unknown"); 1.1140 + } 1.1141 + return request; 1.1142 + } 1.1143 1.1144 - String line; 1.1145 - String body = ""; 1.1146 - do { 1.1147 - line = reader.readLine(); 1.1148 - if (line != null) 1.1149 - body += line + "\n"; 1.1150 - } while (line != null); 1.1151 + private static HttpReport createReportRequest(URI uri, String data, int depth) { 1.1152 + HttpReport request = new HttpReport(); 1.1153 + request.setURI(uri); 1.1154 + //request.setHeader("Host", targetHost.getHostName()); 1.1155 + request.setHeader("Host", targetHost.getHostName() + ":" + String.valueOf(targetHost.getPort())); 1.1156 + request.setHeader("Depth", Integer.toString(depth)); 1.1157 + request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1158 + //request.setHeader("Content-Type", "text/xml;charset=\"UTF-8\""); 1.1159 + try { 1.1160 + request.setEntity(new StringEntity(data)); 1.1161 + } catch (UnsupportedEncodingException e) { 1.1162 + throw new AssertionError("UTF-8 is unknown"); 1.1163 + } 1.1164 + return request; 1.1165 + } 1.1166 1.1167 - calendarEvent.setICSasString(body); 1.1168 + public static void fetchEvent_old(CalendarEvent calendarEvent) 1.1169 + throws ClientProtocolException, IOException { 1.1170 + HttpGet request = null; 1.1171 1.1172 - Log.d(TAG, "HttpResponse GET event status=" + response.getStatusLine() 1.1173 - + " body= " + body); 1.1174 - } 1.1175 - 1.1176 - public static boolean getEvent(CalendarEvent calendarEvent) throws ClientProtocolException, IOException { 1.1177 - boolean Result = false; 1.1178 - HttpReport request = null; 1.1179 + request = new HttpGet(); 1.1180 + request.setURI(calendarEvent.getUri()); 1.1181 + request.setHeader("Host", targetHost.getHostName()); 1.1182 + request.setHeader("Content-Type", "application/xml;charset=\"UTF-8\""); 1.1183 1.1184 - //HINT: bugfix for google calendar: replace("@", "%40") 1.1185 - String data = XML_VERSION + 1.1186 - "<C:calendar-multiget xmlns:D=\"DAV:\" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">" + 1.1187 - "<D:prop>" + 1.1188 - "<D:getetag />" + 1.1189 - "<C:calendar-data />" + 1.1190 - "</D:prop>" + 1.1191 - "<D:href>" + calendarEvent.getUri().getRawPath().replace("@", "%40") + "</D:href>" + 1.1192 - "</C:calendar-multiget>"; 1.1193 + HttpResponse response = httpClient.execute(targetHost, request); 1.1194 + String body = EntityUtils.toString(response.getEntity(), "UTF-8"); 1.1195 1.1196 - URI calendarURI = null; 1.1197 - try { 1.1198 - calendarURI = calendarEvent.calendarURL.toURI(); 1.1199 - } catch (URISyntaxException e) { 1.1200 - e.printStackTrace(); 1.1201 - } 1.1202 - //request = createReportRequest(calendarEvent.getUri(), data, 1); 1.1203 - request = createReportRequest(calendarURI, data, 1); 1.1204 + calendarEvent.setICSasString(body); 1.1205 1.1206 - HttpResponse response = httpClient.execute(targetHost, request); 1.1207 + Log.d(TAG, "HttpResponse GET event status=" + response.getStatusLine() 1.1208 + + " body= " + body); 1.1209 + } 1.1210 1.1211 - BufferedReader reader = new BufferedReader(new InputStreamReader( 1.1212 - response.getEntity().getContent(), "UTF-8")); 1.1213 + public static boolean getEvent(CalendarEvent calendarEvent) throws ClientProtocolException, IOException { 1.1214 + boolean Result = false; 1.1215 + HttpReport request = null; 1.1216 1.1217 - String line; 1.1218 - String body = ""; 1.1219 - do { 1.1220 - line = reader.readLine(); 1.1221 - if (line != null) 1.1222 - body += line + "\n"; 1.1223 - } while (line != null); 1.1224 + //HINT: bugfix for google calendar: replace("@", "%40") 1.1225 + String data = XML_VERSION + 1.1226 + "<C:calendar-multiget xmlns:D=\"DAV:\" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">" + 1.1227 + "<D:prop>" + 1.1228 + "<D:getetag />" + 1.1229 + "<C:calendar-data />" + 1.1230 + "</D:prop>" + 1.1231 + "<D:href>" + calendarEvent.getUri().getRawPath().replace("@", "%40") + "</D:href>" + 1.1232 + "</C:calendar-multiget>"; 1.1233 1.1234 - if (calendarEvent.setICSasMultiStatus(body)) 1.1235 - Result = true; 1.1236 + URI calendarURI = null; 1.1237 + try { 1.1238 + calendarURI = calendarEvent.calendarURL.toURI(); 1.1239 + } catch (URISyntaxException e) { 1.1240 + e.printStackTrace(); 1.1241 + } 1.1242 + //request = createReportRequest(calendarEvent.getUri(), data, 1); 1.1243 + request = createReportRequest(calendarURI, data, 1); 1.1244 1.1245 - return Result; 1.1246 - } 1.1247 - 1.1248 - 1.1249 - /** 1.1250 - * sends a update event request to the server 1.1251 - * @param uri the full URI of the event on server side. example: http://caldav.example.com/principal/user/calendar/e6be67c6-eff0-44f8-a1a0-6c2cb1029944-caldavsyncadapter.ics 1.1252 - * @param data the full ical-data for the event 1.1253 - * @param ETag the ETAG of this event is send within the "If-Match" Parameter to tell the server only to update this version 1.1254 - * @return 1.1255 - */ 1.1256 - public boolean updateEvent(URI uri, String data, String ETag) { 1.1257 - boolean Result = false; 1.1258 - 1.1259 - try { 1.1260 - HttpPut request = createPutRequest(uri, data, 1); 1.1261 - request.addHeader(mstrcHeaderIfMatch, ETag); 1.1262 - HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.1263 - checkStatus(response); 1.1264 - if ((lastStatusCode == 200) || (lastStatusCode == 201) || (lastStatusCode == 204)) { 1.1265 - Result = true; 1.1266 - } else if (lastStatusCode == 412) { 1.1267 - //Precondition failed 1.1268 - Result = false; 1.1269 - } else if (lastStatusCode == 409) { 1.1270 - //Conflict 1.1271 - Result = false; 1.1272 - } else { 1.1273 - Log.w(TAG, "Unkown StatusCode during creation of an event"); 1.1274 - } 1.1275 - } catch (ClientProtocolException e) { 1.1276 - e.printStackTrace(); 1.1277 - } catch (IOException e) { 1.1278 - e.printStackTrace(); 1.1279 - } catch (AuthenticationException e) { 1.1280 - e.printStackTrace(); 1.1281 - } 1.1282 - return Result; 1.1283 - } 1.1284 - 1.1285 - /** 1.1286 - * sends a create event request to server 1.1287 - * @param uri the full URI of the new event on server side. example: http://caldav.example.com/principal/user/calendar/e6be67c6-eff0-44f8-a1a0-6c2cb1029944-caldavsyncadapter.ics 1.1288 - * @param data the full ical-data for the new event 1.1289 - * @return success of this function 1.1290 - */ 1.1291 - public boolean createEvent(URI uri, String data) { 1.1292 - boolean Result = false; 1.1293 - 1.1294 - try { 1.1295 - HttpPut request = createPutRequest(uri, data, 1); 1.1296 - request.addHeader(mstrcHeaderIfNoneMatch, "*"); 1.1297 - HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.1298 - checkStatus(response); 1.1299 - if (lastStatusCode == 201) { 1.1300 - Result = true; 1.1301 - } else { 1.1302 - Log.w(TAG, "Unkown StatusCode during creation of an event"); 1.1303 - } 1.1304 - } catch (ClientProtocolException e) { 1.1305 - e.printStackTrace(); 1.1306 - } catch (IOException e) { 1.1307 - e.printStackTrace(); 1.1308 - } catch (AuthenticationException e) { 1.1309 - e.printStackTrace(); 1.1310 - } 1.1311 - return Result; 1.1312 - } 1.1313 - 1.1314 - /** 1.1315 - * sends a delete event request to the server 1.1316 - * @param calendarEventUri the full URI of the event on server side. example: http://caldav.example.com/principal/user/calendar/e6be67c6-eff0-44f8-a1a0-6c2cb1029944-caldavsyncadapter.ics 1.1317 - * @param ETag the ETAG of this event is send within the "If-Match" Parameter to tell the server only to delete this version 1.1318 - * @return success of this function 1.1319 - */ 1.1320 - public boolean deleteEvent(URI calendarEventUri, String ETag) { 1.1321 - boolean Result = false; 1.1322 - 1.1323 - try { 1.1324 - HttpDelete request = createDeleteRequest(calendarEventUri); 1.1325 - request.addHeader(mstrcHeaderIfMatch, ETag); 1.1326 - HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.1327 - checkStatus(response); 1.1328 - if ((lastStatusCode == 204) || (lastStatusCode == 200)) { 1.1329 - Result = true; 1.1330 - } else { 1.1331 - Log.w(TAG, "Unkown StatusCode during deletion of an event"); 1.1332 - } 1.1333 - } catch (ClientProtocolException e) { 1.1334 - e.printStackTrace(); 1.1335 - } catch (IOException e) { 1.1336 - if (lastStatusCode == 404) { 1.1337 - //the event has already been deleted on server side. no action needed 1.1338 - Result = true; 1.1339 - } else { 1.1340 - e.printStackTrace(); 1.1341 - } 1.1342 - } catch (AuthenticationException e) { 1.1343 - e.printStackTrace(); 1.1344 - } 1.1345 - 1.1346 - return Result; 1.1347 - } 1.1348 - 1.1349 - /** 1.1350 - * returns the ETAG send by the last server response. 1.1351 - * @return the ETAG 1.1352 - */ 1.1353 - public String getLastETag() { 1.1354 - return lastETag; 1.1355 - } 1.1356 - 1.1357 - /** 1.1358 - * returns the DAV-Options send by the last server response. 1.1359 - * @return the DAV-Options 1.1360 - */ 1.1361 - public String getLastDav() { 1.1362 - return lastDav; 1.1363 - } 1.1364 - 1.1365 - public void setVersion(String version) { 1.1366 - VERSION = version; 1.1367 - ((AbstractHttpClient) httpClient).getParams().setParameter(CoreProtocolPNames.USER_AGENT, this.USER_AGENT + " Version:" + VERSION); 1.1368 - } 1.1369 - 1.1370 - public void setAccount(Account account) { 1.1371 - this.mAccount = account; 1.1372 - } 1.1373 - public void setProvider(ContentProviderClient provider) { 1.1374 - this.mProvider = provider; 1.1375 - } 1.1376 -} 1.1377 \ No newline at end of file 1.1378 + HttpResponse response = httpClient.execute(targetHost, request); 1.1379 + String body = EntityUtils.toString(response.getEntity(), "UTF-8"); 1.1380 + 1.1381 + if (calendarEvent.setICSasMultiStatus(body)) 1.1382 + Result = true; 1.1383 + 1.1384 + return Result; 1.1385 + } 1.1386 + 1.1387 + 1.1388 + /** 1.1389 + * sends a update event request to the server 1.1390 + * 1.1391 + * @param uri the full URI of the event on server side. example: http://caldav.example.com/principal/user/calendar/e6be67c6-eff0-44f8-a1a0-6c2cb1029944-caldavsyncadapter.ics 1.1392 + * @param data the full ical-data for the event 1.1393 + * @param ETag the ETAG of this event is send within the "If-Match" Parameter to tell the server only to update this version 1.1394 + * @return 1.1395 + */ 1.1396 + public boolean updateEvent(URI uri, String data, String ETag) { 1.1397 + boolean Result = false; 1.1398 + 1.1399 + try { 1.1400 + HttpPut request = createPutRequest(uri, data, 1); 1.1401 + request.addHeader(mstrcHeaderIfMatch, ETag); 1.1402 + HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.1403 + checkStatus(response); 1.1404 + if ((lastStatusCode == 200) || (lastStatusCode == 201) || (lastStatusCode == 204)) { 1.1405 + Result = true; 1.1406 + } else if (lastStatusCode == 412) { 1.1407 + //Precondition failed 1.1408 + Result = false; 1.1409 + } else if (lastStatusCode == 409) { 1.1410 + //Conflict 1.1411 + Result = false; 1.1412 + } else { 1.1413 + Log.w(TAG, "Unkown StatusCode during creation of an event"); 1.1414 + } 1.1415 + } catch (ClientProtocolException e) { 1.1416 + e.printStackTrace(); 1.1417 + } catch (IOException e) { 1.1418 + e.printStackTrace(); 1.1419 + } catch (AuthenticationException e) { 1.1420 + e.printStackTrace(); 1.1421 + } 1.1422 + return Result; 1.1423 + } 1.1424 + 1.1425 + /** 1.1426 + * sends a create event request to server 1.1427 + * 1.1428 + * @param uri the full URI of the new event on server side. example: http://caldav.example.com/principal/user/calendar/e6be67c6-eff0-44f8-a1a0-6c2cb1029944-caldavsyncadapter.ics 1.1429 + * @param data the full ical-data for the new event 1.1430 + * @return success of this function 1.1431 + */ 1.1432 + public boolean createEvent(URI uri, String data) { 1.1433 + boolean Result = false; 1.1434 + 1.1435 + try { 1.1436 + HttpPut request = createPutRequest(uri, data, 1); 1.1437 + request.addHeader(mstrcHeaderIfNoneMatch, "*"); 1.1438 + HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.1439 + checkStatus(response); 1.1440 + if (lastStatusCode == 201) { 1.1441 + Result = true; 1.1442 + } else { 1.1443 + Log.w(TAG, "Unkown StatusCode during creation of an event"); 1.1444 + } 1.1445 + } catch (ClientProtocolException e) { 1.1446 + e.printStackTrace(); 1.1447 + } catch (IOException e) { 1.1448 + e.printStackTrace(); 1.1449 + } catch (AuthenticationException e) { 1.1450 + e.printStackTrace(); 1.1451 + } 1.1452 + return Result; 1.1453 + } 1.1454 + 1.1455 + /** 1.1456 + * sends a delete event request to the server 1.1457 + * 1.1458 + * @param calendarEventUri the full URI of the event on server side. example: http://caldav.example.com/principal/user/calendar/e6be67c6-eff0-44f8-a1a0-6c2cb1029944-caldavsyncadapter.ics 1.1459 + * @param ETag the ETAG of this event is send within the "If-Match" Parameter to tell the server only to delete this version 1.1460 + * @return success of this function 1.1461 + */ 1.1462 + public boolean deleteEvent(URI calendarEventUri, String ETag) { 1.1463 + boolean Result = false; 1.1464 + 1.1465 + try { 1.1466 + HttpDelete request = createDeleteRequest(calendarEventUri); 1.1467 + request.addHeader(mstrcHeaderIfMatch, ETag); 1.1468 + HttpResponse response = httpClient.execute(targetHost, request, mContext); 1.1469 + checkStatus(response); 1.1470 + if ((lastStatusCode == 204) || (lastStatusCode == 200)) { 1.1471 + Result = true; 1.1472 + } else { 1.1473 + Log.w(TAG, "Unkown StatusCode during deletion of an event"); 1.1474 + } 1.1475 + } catch (ClientProtocolException e) { 1.1476 + e.printStackTrace(); 1.1477 + } catch (IOException e) { 1.1478 + if (lastStatusCode == 404) { 1.1479 + //the event has already been deleted on server side. no action needed 1.1480 + Result = true; 1.1481 + } else { 1.1482 + e.printStackTrace(); 1.1483 + } 1.1484 + } catch (AuthenticationException e) { 1.1485 + e.printStackTrace(); 1.1486 + } 1.1487 + 1.1488 + return Result; 1.1489 + } 1.1490 + 1.1491 + /** 1.1492 + * returns the ETAG send by the last server response. 1.1493 + * 1.1494 + * @return the ETAG 1.1495 + */ 1.1496 + public String getLastETag() { 1.1497 + return lastETag; 1.1498 + } 1.1499 + 1.1500 + /** 1.1501 + * returns the DAV-Options send by the last server response. 1.1502 + * 1.1503 + * @return the DAV-Options 1.1504 + */ 1.1505 + public String getLastDav() { 1.1506 + return lastDav; 1.1507 + } 1.1508 + 1.1509 + public void setVersion(String version) { 1.1510 + VERSION = version; 1.1511 + ((AbstractHttpClient) httpClient).getParams() 1.1512 + .setParameter(CoreProtocolPNames.USER_AGENT, this.USER_AGENT + " Version:" + VERSION); 1.1513 + } 1.1514 + 1.1515 + public void setAccount(Account account) { 1.1516 + this.mAccount = account; 1.1517 + } 1.1518 + 1.1519 + public void setProvider(ContentProviderClient provider) { 1.1520 + this.mProvider = provider; 1.1521 + } 1.1522 +}