src/org/gege/caldavsyncadapter/caldav/CaldavFacade.java

changeset 8
ec8af0e3fbc2
parent 0
fb9019fb1bf7
     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 +}

mercurial