src/org/gege/caldavsyncadapter/caldav/entities/CalendarEvent.java

changeset 0
fb9019fb1bf7
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/org/gege/caldavsyncadapter/caldav/entities/CalendarEvent.java	Tue Feb 10 18:12:00 2015 +0100
     1.3 @@ -0,0 +1,1068 @@
     1.4 +/**
     1.5 + * Copyright (c) 2012-2013, Gerald Garcia, Timo Berger
     1.6 + * 
     1.7 + * This file is part of Andoid Caldav Sync Adapter Free.
     1.8 + *
     1.9 + * Andoid Caldav Sync Adapter Free is free software: you can redistribute 
    1.10 + * it and/or modify it under the terms of the GNU General Public License 
    1.11 + * as published by the Free Software Foundation, either version 3 of the 
    1.12 + * License, or at your option any later version.
    1.13 + *
    1.14 + * Andoid Caldav Sync Adapter Free is distributed in the hope that 
    1.15 + * it will be useful, but WITHOUT ANY WARRANTY; without even the implied 
    1.16 + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.17 + * GNU General Public License for more details.
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License
    1.20 + * along with Andoid Caldav Sync Adapter Free.  
    1.21 + * If not, see <http://www.gnu.org/licenses/>.
    1.22 + * 
    1.23 + */
    1.24 +
    1.25 +package org.gege.caldavsyncadapter.caldav.entities;
    1.26 +
    1.27 +import java.io.IOException;
    1.28 +import java.io.StringReader;
    1.29 +import java.io.UnsupportedEncodingException;
    1.30 +import java.net.URI;
    1.31 +import java.net.URL;
    1.32 +import java.net.URLDecoder;
    1.33 +import java.text.ParseException;
    1.34 +import java.util.ArrayList;
    1.35 +
    1.36 +import javax.xml.parsers.ParserConfigurationException;
    1.37 +import javax.xml.parsers.SAXParser;
    1.38 +import javax.xml.parsers.SAXParserFactory;
    1.39 +
    1.40 +import net.fortuna.ical4j.data.CalendarBuilder;
    1.41 +import net.fortuna.ical4j.data.ParserException;
    1.42 +import net.fortuna.ical4j.model.Calendar;
    1.43 +import net.fortuna.ical4j.model.Component;
    1.44 +import net.fortuna.ical4j.model.ComponentList;
    1.45 +import net.fortuna.ical4j.model.DateTime;
    1.46 +import net.fortuna.ical4j.model.Dur;
    1.47 +import net.fortuna.ical4j.model.Parameter;
    1.48 +import net.fortuna.ical4j.model.ParameterList;
    1.49 +import net.fortuna.ical4j.model.Property;
    1.50 +import net.fortuna.ical4j.model.PropertyList;
    1.51 +import net.fortuna.ical4j.model.TimeZone;
    1.52 +import net.fortuna.ical4j.model.component.VEvent;
    1.53 +import net.fortuna.ical4j.model.component.VTimeZone;
    1.54 +import net.fortuna.ical4j.model.parameter.Cn;
    1.55 +import net.fortuna.ical4j.model.parameter.CuType;
    1.56 +import net.fortuna.ical4j.model.parameter.PartStat;
    1.57 +import net.fortuna.ical4j.model.parameter.Role;
    1.58 +import net.fortuna.ical4j.model.property.Clazz;
    1.59 +import net.fortuna.ical4j.model.property.Status;
    1.60 +import net.fortuna.ical4j.util.CompatibilityHints;
    1.61 +
    1.62 +import org.apache.http.client.ClientProtocolException;
    1.63 +import org.gege.caldavsyncadapter.Event;
    1.64 +import org.gege.caldavsyncadapter.android.entities.AndroidEvent;
    1.65 +import org.gege.caldavsyncadapter.caldav.CaldavFacade;
    1.66 +import org.gege.caldavsyncadapter.caldav.CaldavProtocolException;
    1.67 +import org.gege.caldavsyncadapter.caldav.xml.MultiStatusHandler;
    1.68 +import org.gege.caldavsyncadapter.caldav.xml.sax.MultiStatus;
    1.69 +import org.gege.caldavsyncadapter.caldav.xml.sax.Prop;
    1.70 +import org.gege.caldavsyncadapter.caldav.xml.sax.PropStat;
    1.71 +import org.gege.caldavsyncadapter.caldav.xml.sax.Response;
    1.72 +import org.gege.caldavsyncadapter.syncadapter.SyncAdapter;
    1.73 +import org.xml.sax.InputSource;
    1.74 +import org.xml.sax.SAXException;
    1.75 +import org.xml.sax.XMLReader;
    1.76 +
    1.77 +import android.accounts.Account;
    1.78 +import android.content.ContentProviderClient;
    1.79 +import android.content.ContentUris;
    1.80 +import android.content.ContentValues;
    1.81 +import android.content.SyncStats;
    1.82 +import android.database.Cursor;
    1.83 +import android.net.Uri;
    1.84 +import android.os.RemoteException;
    1.85 +import android.provider.CalendarContract.Attendees;
    1.86 +import android.provider.CalendarContract.Calendars;
    1.87 +import android.provider.CalendarContract.Events;
    1.88 +import android.provider.CalendarContract.Reminders;
    1.89 +import android.util.Log;
    1.90 +
    1.91 +
    1.92 +
    1.93 +public class CalendarEvent extends org.gege.caldavsyncadapter.Event {
    1.94 +	private static final String TAG = "CalendarEvent";
    1.95 +	
    1.96 +	private String stringIcs;
    1.97 +	
    1.98 +	private Calendar calendar;
    1.99 +
   1.100 +	private Component calendarComponent;
   1.101 +	
   1.102 +	private String eTag;
   1.103 +	private URI muri;
   1.104 +	private Uri mAndroidEventUri;
   1.105 +	public URL calendarURL;
   1.106 +	
   1.107 +	private boolean mAllDay = false;
   1.108 +	private VTimeZone mVTimeZone = null; 
   1.109 +	private TimeZone mTimeZone = null; 
   1.110 +	
   1.111 +	private String mstrTimeZoneStart = "";
   1.112 +	private String mstrTimeZoneEnd = "";
   1.113 +
   1.114 +	private Account mAccount = null;
   1.115 +	private ContentProviderClient mProvider = null;
   1.116 +	
   1.117 +	public CalendarEvent(Account account, ContentProviderClient provider) {
   1.118 +		this.mAccount = account;
   1.119 +		this.mProvider = provider;
   1.120 +	}
   1.121 +	
   1.122 +	public String getETag() {
   1.123 +		return eTag;
   1.124 +	}
   1.125 +
   1.126 +	public void setETag(String eTag) {
   1.127 +		this.eTag = eTag;
   1.128 +	}
   1.129 +	
   1.130 +	public URI getUri() {
   1.131 +		return muri;
   1.132 +	}
   1.133 +
   1.134 +	public void setUri(URI uri) {
   1.135 +		this.muri = uri;
   1.136 +	}
   1.137 +
   1.138 +	public void setICSasString(String ics) {
   1.139 +		this.stringIcs = ics;
   1.140 +	}
   1.141 +	
   1.142 +	public boolean setICSasMultiStatus(String stringMultiStatus) {
   1.143 +		boolean Result = false;
   1.144 +		String ics = "";
   1.145 +		MultiStatus multistatus;
   1.146 +		ArrayList<Response> responselist;
   1.147 +		Response response;
   1.148 +		PropStat propstat;
   1.149 +		Prop prop;
   1.150 +		try {
   1.151 +			SAXParserFactory factory = SAXParserFactory.newInstance();
   1.152 +			SAXParser parser = factory.newSAXParser();
   1.153 +			XMLReader reader = parser.getXMLReader();
   1.154 +			MultiStatusHandler contentHandler = new MultiStatusHandler(); 
   1.155 +			reader.setContentHandler(contentHandler);
   1.156 +			reader.parse(new InputSource(new StringReader(stringMultiStatus)));
   1.157 +			
   1.158 +			multistatus = contentHandler.mMultiStatus;
   1.159 +			if (multistatus != null) {
   1.160 +				responselist = multistatus.ResponseList;
   1.161 +				if (responselist.size() == 1) {
   1.162 +					response = responselist.get(0);
   1.163 +					//HINT: bugfix for google calendar, zimbra replace("@", "%40")
   1.164 +					if (response.href.replace("@", "%40").equals(this.getUri().getRawPath().replace("@", "%40"))) {
   1.165 +						propstat = response.propstat;
   1.166 +						if (propstat != null) {
   1.167 +							if (propstat.status.contains("200 OK")) {
   1.168 +								prop = propstat.prop;
   1.169 +								ics = prop.calendardata;
   1.170 +								this.setETag(prop.getetag);
   1.171 +								Result = true;
   1.172 +							}
   1.173 +						}
   1.174 +					}
   1.175 +				}
   1.176 +			}
   1.177 +		} catch (ParserConfigurationException e1) {
   1.178 +			e1.printStackTrace();
   1.179 +		} catch (SAXException e1) {
   1.180 +			e1.printStackTrace();
   1.181 +		} catch (IOException e) {
   1.182 +			e.printStackTrace();
   1.183 +		}
   1.184 +		
   1.185 +		this.stringIcs = ics;
   1.186 +		return Result;
   1.187 +	}
   1.188 +	
   1.189 +	/**
   1.190 +	 * sets the Uri of the android event
   1.191 +	 * @param uri
   1.192 +	 * @see org.gege.caldavsyncadapter.syncadapter.SyncAdapter#createAndroidEvent(ContentProviderClient provider, Account account, Uri calendarUri, CalendarEvent calendarEvent)
   1.193 +	 * @see org.gege.caldavsyncadapter.syncadapter.SyncAdapter#updateAndroidEvent(ContentProviderClient provider, Account account, AndroidEvent androidEvent, CalendarEvent calendarEvent)
   1.194 +	 */
   1.195 +	public void setAndroidEventUri(Uri uri) {
   1.196 +		mAndroidEventUri = uri;
   1.197 +	}
   1.198 +	
   1.199 +	/**
   1.200 +	 * gets the Uri of the android event
   1.201 +	 * @return
   1.202 +	 */
   1.203 +	public Uri getAndroidEventUri() {
   1.204 +		return mAndroidEventUri;
   1.205 +	}
   1.206 +	
   1.207 +	
   1.208 +	/**
   1.209 +	 * reads all ContentValues from the caldav source
   1.210 +	 * @param calendarUri
   1.211 +	 * @return
   1.212 +	 * @see org.gege.caldavsyncadapter.syncadapter.SyncAdapter#createAndroidEvent(ContentProviderClient provider, Account account, Uri calendarUri, CalendarEvent calendarEvent)
   1.213 +	 * @see org.gege.caldavsyncadapter.syncadapter.SyncAdapter#updateAndroidEvent(ContentProviderClient provider, Account account, AndroidEvent androidEvent, CalendarEvent calendarEvent)
   1.214 +	 */
   1.215 +	public boolean readContentValues() {
   1.216 +		this.ContentValues.put(Events.DTSTART, this.getStartTime());
   1.217 +		this.ContentValues.put(Events.EVENT_TIMEZONE, this.getTimeZoneStart());
   1.218 +
   1.219 +		//if (this.getRRule().isEmpty() && this.getRDate().isEmpty()) {
   1.220 +		if (this.getRRule() == null && this.getRDate() == null) {
   1.221 +			//if (AllDay.equals(1)) //{
   1.222 +			//	values.put(Events.ALL_DAY, AllDay);
   1.223 +			//} else {
   1.224 +			this.ContentValues.put(Events.DTEND, this.getEndTime());
   1.225 +			this.ContentValues.put(Events.EVENT_END_TIMEZONE, this.getTimeZoneEnd());
   1.226 +			//}
   1.227 +		} else {
   1.228 +			//if (AllDay.equals(1))
   1.229 +			//	values.put(Events.ALL_DAY, AllDay);
   1.230 +			this.ContentValues.put(Events.DURATION, this.getDuration());
   1.231 +		}
   1.232 +		int AllDay = this.getAllDay();
   1.233 +		this.ContentValues.put(Events.ALL_DAY, AllDay);
   1.234 +		
   1.235 +		this.ContentValues.put(Events.TITLE, this.getTitle());
   1.236 +		//this.ContentValues.put(Events.CALENDAR_ID, ContentUris.parseId(calendarUri));
   1.237 +		this.ContentValues.put(Events._SYNC_ID, this.getUri().toString());
   1.238 +		this.ContentValues.put(ETAG, this.getETag());
   1.239 +		this.ContentValues.put(Events.DESCRIPTION, this.getDescription());
   1.240 +		this.ContentValues.put(Events.EVENT_LOCATION, this.getLocation());
   1.241 +		this.ContentValues.put(Events.ACCESS_LEVEL, this.getAccessLevel());
   1.242 +		this.ContentValues.put(Events.STATUS, this.getStatus());
   1.243 +		this.ContentValues.put(Events.RDATE, this.getRDate());
   1.244 +		this.ContentValues.put(Events.RRULE, this.getRRule());
   1.245 +		this.ContentValues.put(Events.EXRULE, this.getExRule());
   1.246 +		this.ContentValues.put(Events.EXDATE, this.getExDate());
   1.247 +		this.ContentValues.put(UID, this.getUid());
   1.248 +		this.ContentValues.put(RAWDATA, this.stringIcs);
   1.249 +		
   1.250 +		return true;
   1.251 +	}
   1.252 +
   1.253 +	/**
   1.254 +	 * receives a single event and parses its content
   1.255 +	 * @return success of this function
   1.256 +	 * @see CalendarEvent#parseIcs()
   1.257 +	 * @throws ClientProtocolException
   1.258 +	 * @throws IOException
   1.259 +	 * @throws CaldavProtocolException
   1.260 +	 * @throws ParserException
   1.261 +	 */
   1.262 +	public boolean fetchBody() throws ClientProtocolException, IOException, CaldavProtocolException, ParserException {
   1.263 +		boolean Error = false;
   1.264 +		
   1.265 +		//replaced fetchEvent() with getEvent()
   1.266 +		//CaldavFacade.fetchEvent(this);
   1.267 +		CaldavFacade.getEvent(this);
   1.268 +		
   1.269 +		boolean Parse = this.parseIcs();
   1.270 +		if (!Parse)
   1.271 +			Error = true;
   1.272 +		
   1.273 +		return !Error;
   1.274 +	}
   1.275 +	
   1.276 +	public java.util.ArrayList<ContentValues> getReminders() {
   1.277 +		java.util.ArrayList<ContentValues> Result = new java.util.ArrayList<ContentValues>();
   1.278 +		ContentValues Reminder;
   1.279 +		
   1.280 +		/*
   1.281 +		 * http://sourceforge.net/tracker/?func=detail&aid=3021704&group_id=107024&atid=646395
   1.282 +		 */
   1.283 +
   1.284 +		net.fortuna.ical4j.model.component.VEvent event = (VEvent) this.calendarComponent;
   1.285 +
   1.286 +		//ComponentList ComList = this.calendar.getComponents(Component.VALARM);
   1.287 +		ComponentList ComList = event.getAlarms();
   1.288 +
   1.289 +		if (ComList != null) {
   1.290 +			for (Object objCom : ComList) {
   1.291 +				Component Com = (Component) objCom;
   1.292 +				Reminder = new ContentValues();
   1.293 +				
   1.294 +				//Property ACTION = Com.getProperty("ACTION");
   1.295 +				Property TRIGGER = Com.getProperty("TRIGGER");
   1.296 +				if (TRIGGER != null) {
   1.297 +					Dur Duration = new Dur(TRIGGER.getValue());
   1.298 +					//if (ACTION.getValue().equals("DISPLAY"))
   1.299 +					
   1.300 +					int intDuration = Duration.getMinutes() + Duration.getHours() * 60 + Duration.getDays() * 60 * 24;
   1.301 +					
   1.302 +					Reminder.put(Reminders.EVENT_ID, ContentUris.parseId(mAndroidEventUri));
   1.303 +					Reminder.put(Reminders.METHOD, Reminders.METHOD_ALERT);
   1.304 +					Reminder.put(Reminders.MINUTES, intDuration);
   1.305 +					
   1.306 +					Result.add(Reminder);
   1.307 +				}
   1.308 +			}
   1.309 +		}
   1.310 +		return Result;
   1.311 +	}
   1.312 +	
   1.313 +	public java.util.ArrayList<ContentValues> getAttandees() {
   1.314 +		java.util.ArrayList<ContentValues> Result = new java.util.ArrayList<ContentValues>();
   1.315 +		ContentValues Attendee;
   1.316 +		PropertyList Propertys = calendarComponent.getProperties(Property.ATTENDEE);
   1.317 +		if (Propertys != null) {
   1.318 +			for (Object objProperty : Propertys){
   1.319 +				Property property = (Property) objProperty;
   1.320 +				Attendee = ReadAttendeeProperties(property,Property.ATTENDEE);
   1.321 +				if (Attendee != null)
   1.322 +					Result.add(Attendee);
   1.323 +			}
   1.324 +		}
   1.325 +		Propertys = calendarComponent.getProperties(Property.ORGANIZER);
   1.326 +		if (Propertys != null) {
   1.327 +			for (Object objProperty : Propertys){
   1.328 +				Property property = (Property) objProperty;
   1.329 +				Attendee = ReadAttendeeProperties(property,Property.ORGANIZER);
   1.330 +				if (Attendee != null)
   1.331 +					Result.add(Attendee);
   1.332 +			}
   1.333 +		}
   1.334 +		
   1.335 +		
   1.336 +		return Result;
   1.337 +	}
   1.338 +	
   1.339 +	private String mstrcIcalPropertyError = "net.fortunal.ical4j.invalid:";
   1.340 +	private ContentValues ReadAttendeeProperties(Property property, String Type) {
   1.341 +		ContentValues Attendee = null;
   1.342 +		
   1.343 +		ParameterList Parameters = property.getParameters();
   1.344 +		Parameter CN       = Parameters.getParameter(Cn.CN);
   1.345 +		Parameter ROLE     = Parameters.getParameter(Role.ROLE);
   1.346 +		Parameter CUTYPE   = Parameters.getParameter(CuType.CUTYPE);
   1.347 +		//Parameter RSVP     = Parameters.getParameter("RSVP");
   1.348 +		Parameter PARTSTAT = Parameters.getParameter(PartStat.PARTSTAT);
   1.349 +
   1.350 +		String strCN = "";
   1.351 +		String strROLE = "";
   1.352 +		String strCUTYPE = "";
   1.353 +		String strValue = property.getValue().replace("mailto:", "");
   1.354 +		String strPARTSTAT = "";
   1.355 +		
   1.356 +		if (strValue.startsWith(mstrcIcalPropertyError)) {
   1.357 +			strValue = strValue.replace(mstrcIcalPropertyError, "");
   1.358 +			try {
   1.359 +				strValue = URLDecoder.decode(strValue, "UTF-8");
   1.360 +			} catch (UnsupportedEncodingException e) {
   1.361 +				e.printStackTrace();
   1.362 +			}
   1.363 +		}
   1.364 +		
   1.365 +		if (CN != null)
   1.366 +			strCN = CN.getValue();
   1.367 +		if (ROLE != null)
   1.368 +			strROLE = ROLE.getValue();
   1.369 +		if (CUTYPE != null)
   1.370 +			strCUTYPE = CUTYPE.getValue();
   1.371 +		if (PARTSTAT != null)
   1.372 +			strPARTSTAT = PARTSTAT.getValue();
   1.373 +		
   1.374 +		if (strCN.equals("")) {
   1.375 +			if (!strValue.equals("")) {
   1.376 +				strCN = strValue;
   1.377 +			}
   1.378 +		}
   1.379 +
   1.380 +		if (!strCN.equals("")) {
   1.381 +			if (strCUTYPE.equals("") || strCUTYPE.equals("INDIVIDUAL")) {
   1.382 +				Attendee = new ContentValues();
   1.383 +				
   1.384 +				Attendee.put(Attendees.EVENT_ID, ContentUris.parseId(mAndroidEventUri));
   1.385 +
   1.386 +				Attendee.put(Attendees.ATTENDEE_NAME, strCN);
   1.387 +				Attendee.put(Attendees.ATTENDEE_EMAIL, strValue);
   1.388 +
   1.389 +				if (strROLE.equals("OPT-PARTICIPANT"))
   1.390 +					Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);
   1.391 +				else if (strROLE.equals("NON-PARTICIPANT"))
   1.392 +					Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_NONE);
   1.393 +				else if (strROLE.equals("REQ-PARTICIPANT"))
   1.394 +					Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_REQUIRED);
   1.395 +				else if (strROLE.equals("CHAIR"))
   1.396 +					Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_REQUIRED);
   1.397 +				else 
   1.398 +					Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_NONE);
   1.399 +				
   1.400 +				if (Type.equals(Property.ATTENDEE))
   1.401 +					Attendee.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
   1.402 +				else if (Type.equals(Property.ORGANIZER))
   1.403 +					Attendee.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ORGANIZER);
   1.404 +				else
   1.405 +					Attendee.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_NONE);
   1.406 +
   1.407 +				if (strPARTSTAT.equals(PartStat.NEEDS_ACTION.getValue()))
   1.408 +					Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
   1.409 +				else if (strPARTSTAT.equals(PartStat.ACCEPTED.getValue()))
   1.410 +					Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_ACCEPTED);
   1.411 +				else if (strPARTSTAT.equals(PartStat.DECLINED.getValue()))
   1.412 +					Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_DECLINED);
   1.413 +				else if (strPARTSTAT.equals(PartStat.COMPLETED.getValue()))
   1.414 +					Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_NONE);
   1.415 +				else if (strPARTSTAT.equals(PartStat.TENTATIVE.getValue()))
   1.416 +					Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_TENTATIVE);
   1.417 +				else
   1.418 +					Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
   1.419 +
   1.420 +			}
   1.421 +		}
   1.422 +		
   1.423 +		return Attendee;
   1.424 +	}
   1.425 +	
   1.426 +	private long getAccessLevel() {
   1.427 +		long Result = Events.ACCESS_DEFAULT;
   1.428 +		String Value = "";
   1.429 +		Property property = calendarComponent.getProperty(Property.CLASS);
   1.430 +		if (property != null) {
   1.431 +			Value = property.getValue();
   1.432 +			if (Value.equals(Clazz.PUBLIC))
   1.433 +				Result = Events.ACCESS_PUBLIC;
   1.434 +			else if (Value.equals(Clazz.PRIVATE))
   1.435 +				Result = Events.ACCESS_PRIVATE;
   1.436 +			else if (Value.equals(Clazz.CONFIDENTIAL))
   1.437 +				Result = Events.ACCESS_PRIVATE; // should be ACCESS_CONFIDENTIAL, but is not implemented within Android
   1.438 +		}
   1.439 +		
   1.440 +		return Result;
   1.441 +	}
   1.442 +	
   1.443 +	private int getStatus() {
   1.444 +		int Result = -1;
   1.445 +		String Value = "";
   1.446 +		Property property = calendarComponent.getProperty(Property.STATUS);
   1.447 +		if (property != null) {
   1.448 +			Value = property.getValue();
   1.449 +			if (Value.equals(Status.VEVENT_CONFIRMED.getValue()))
   1.450 +				Result = Events.STATUS_CONFIRMED;
   1.451 +			else if (Value.equals(Status.VEVENT_CANCELLED.getValue()))
   1.452 +				Result = Events.STATUS_CANCELED;
   1.453 +			else if (Value.equals(Status.VEVENT_TENTATIVE.getValue()))
   1.454 +				Result = Events.STATUS_TENTATIVE;
   1.455 +		}
   1.456 +		
   1.457 +		return Result;
   1.458 +	}
   1.459 +	
   1.460 +	private String getDescription() {
   1.461 +		String Result = null;
   1.462 +		Property property = calendarComponent.getProperty(Property.DESCRIPTION);
   1.463 +		if (property != null)
   1.464 +			Result = property.getValue();
   1.465 +		
   1.466 +		return Result;
   1.467 +	}
   1.468 +	
   1.469 +	private String getLocation() {
   1.470 +		String Result = null;
   1.471 +		Property property = calendarComponent.getProperty(Property.LOCATION);
   1.472 +		if (property != null) 
   1.473 +			Result = property.getValue();
   1.474 +		
   1.475 +		return Result;
   1.476 +	}
   1.477 +
   1.478 +	private String getTitle() {
   1.479 +		Property property = calendarComponent.getProperty(Property.SUMMARY);
   1.480 +		if (property != null)
   1.481 +			return property.getValue();
   1.482 +		else
   1.483 +			return "**unkonwn**";
   1.484 +	}
   1.485 +	
   1.486 +	private String getRRule() {
   1.487 +		String Result = null;
   1.488 +		Property property = calendarComponent.getProperty(Property.RRULE);
   1.489 +		if (property != null)
   1.490 +			Result = property.getValue();
   1.491 +
   1.492 +		return Result;
   1.493 +	}
   1.494 +
   1.495 +	private String getExRule() {
   1.496 +		String Result = null;
   1.497 +		Property property = calendarComponent.getProperty(Property.EXRULE);
   1.498 +		if (property != null)
   1.499 +			Result = property.getValue();
   1.500 +
   1.501 +		return Result;
   1.502 +	}
   1.503 +	
   1.504 +	private String getRDate() {
   1.505 +		String Result = null;
   1.506 +		
   1.507 +		java.util.ArrayList<String> ExDates = this.getRDates();
   1.508 +		for (String Value: ExDates) {
   1.509 +			if (Result == null)
   1.510 +				Result = "";
   1.511 +			if (!Result.isEmpty())
   1.512 +				Result += ",";
   1.513 +			Result += Value;
   1.514 +		}
   1.515 +		
   1.516 +		return Result;
   1.517 +	}
   1.518 +	
   1.519 +	private java.util.ArrayList<String> getRDates() {
   1.520 +		java.util.ArrayList<String> Result = new java.util.ArrayList<String>();
   1.521 +		PropertyList Propertys = calendarComponent.getProperties(Property.RDATE);
   1.522 +		if (Propertys != null) {
   1.523 +			Property property;
   1.524 +			for (Object objProperty : Propertys){
   1.525 +				property = (Property) objProperty;
   1.526 +				Result.add(property.getValue());
   1.527 +			}
   1.528 +		}
   1.529 +
   1.530 +		return Result;
   1.531 +	}
   1.532 +	
   1.533 +	private String getExDate() {
   1.534 +		String Result = null;
   1.535 +		
   1.536 +		java.util.ArrayList<String> ExDates = this.getExDates();
   1.537 +		for (String Value: ExDates) {
   1.538 +			if (Result == null)
   1.539 +				Result = "";
   1.540 +			if (!Result.isEmpty())
   1.541 +				Result += ",";
   1.542 +			Result += Value;
   1.543 +		}
   1.544 +		
   1.545 +		return Result;
   1.546 +	}
   1.547 +	
   1.548 +	private java.util.ArrayList<String> getExDates() {
   1.549 +		java.util.ArrayList<String> Result = new java.util.ArrayList<String>();
   1.550 +		PropertyList Propertys = calendarComponent.getProperties(Property.EXDATE);
   1.551 +		if (Propertys != null) {
   1.552 +			Property property;
   1.553 +			for (Object objProperty : Propertys){
   1.554 +				property = (Property) objProperty;
   1.555 +				Result.add(property.getValue());
   1.556 +			}
   1.557 +		}
   1.558 +
   1.559 +		return Result;
   1.560 +	}
   1.561 +	
   1.562 +	private String getUid() {
   1.563 +		String Result = "";
   1.564 +		Property prop = calendarComponent.getProperty(Property.UID);
   1.565 +		if (prop != null) {
   1.566 +			Result = prop.getValue();
   1.567 +		}
   1.568 +		
   1.569 +		return Result;
   1.570 +	}
   1.571 +	
   1.572 +	private Long getTimestamp(Property prop) {
   1.573 +		Long Result = null;
   1.574 +		String strTimeZone = "";
   1.575 +		//TimeZone timeZone = null;
   1.576 +		
   1.577 +		try {
   1.578 +			String strDate = prop.getValue();
   1.579 +			
   1.580 +			Parameter parAllDay = prop.getParameter("VALUE");
   1.581 +			if (parAllDay != null) {
   1.582 +				if (parAllDay.getValue().equals("DATE")) {
   1.583 +					mAllDay = true;
   1.584 +					strDate += "T000000Z";
   1.585 +				}
   1.586 +			}
   1.587 +			
   1.588 +			Parameter propTZ = prop.getParameter(Property.TZID);
   1.589 +			if (propTZ != null)
   1.590 +				strTimeZone = propTZ.getValue();
   1.591 +			
   1.592 +			//TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
   1.593 +			//if (!strTimeZone.equals(""))
   1.594 +			//	timeZone = registry.getTimeZone(strTimeZone);
   1.595 +
   1.596 +			//if (timeZone != null) {
   1.597 +			if (!strTimeZone.equals("")) {
   1.598 +				//Result = new DateTime(strDate, timeZone);
   1.599 +				//Result1 = Result.getTime();
   1.600 +				
   1.601 +				//20130331T120000
   1.602 +				int Year = Integer.parseInt(strDate.substring(0, 4));
   1.603 +				int Month = Integer.parseInt(strDate.substring(4, 6)) - 1;
   1.604 +				int Day = Integer.parseInt(strDate.substring(6, 8));
   1.605 +				int Hour = Integer.parseInt(strDate.substring(9, 11));
   1.606 +				int Minute = Integer.parseInt(strDate.substring(11, 13));
   1.607 +				int Second = Integer.parseInt(strDate.substring(13, 15));
   1.608 +
   1.609 +				// time in UTC
   1.610 +				java.util.TimeZone jtz = java.util.TimeZone.getTimeZone("UTC");
   1.611 +				java.util.Calendar cal = java.util.GregorianCalendar.getInstance(jtz);
   1.612 +				cal.set(Year, Month, Day, Hour, Minute, Second);
   1.613 +				cal.set(java.util.Calendar.MILLISECOND, 0);
   1.614 +				Result = cal.getTimeInMillis();
   1.615 +				
   1.616 +				// get the timezone
   1.617 +				String[] IDs = java.util.TimeZone.getAvailableIDs();
   1.618 +				Boolean Found = false;
   1.619 +				for (int i = 0; i < IDs.length; i++) {
   1.620 +					Found = Found || IDs[i].equals(strTimeZone);
   1.621 +				}
   1.622 +				if (Found) {
   1.623 +					jtz = java.util.TimeZone.getTimeZone(strTimeZone);
   1.624 +					
   1.625 +					// subtract the offset
   1.626 +					Result -= jtz.getRawOffset();
   1.627 +					
   1.628 +					// remove dst
   1.629 +					if (jtz.inDaylightTime(new java.util.Date(Result)))
   1.630 +						Result -= jtz.getDSTSavings();
   1.631 +
   1.632 +				} else {
   1.633 +					if (mTimeZone != null) {
   1.634 +						// subtract the offset
   1.635 +						Result -= mTimeZone.getRawOffset();
   1.636 +					
   1.637 +						// remove dst
   1.638 +						if (mTimeZone.inDaylightTime(new java.util.Date(Result)))
   1.639 +							Result -= mTimeZone.getDSTSavings();
   1.640 +					} else {
   1.641 +						// unknown Time?
   1.642 +						// treat as local time, should not happen too often :)
   1.643 +						Result = new DateTime(strDate).getTime();
   1.644 +					}
   1.645 +				}
   1.646 +			} else {
   1.647 +				if (strDate.endsWith("Z")) {
   1.648 +					// GMT or UTC
   1.649 +					Result = new DateTime(strDate).getTime();
   1.650 +				} else {
   1.651 +					// unknown Time?
   1.652 +					// treat as local time, should not happen too often :)
   1.653 +					Result = new DateTime(strDate).getTime();
   1.654 +				}
   1.655 +			}
   1.656 +
   1.657 +		} catch (ParseException e) {
   1.658 +			e.printStackTrace();
   1.659 +		}
   1.660 +		
   1.661 +		return Result;
   1.662 +	}
   1.663 +	
   1.664 +	private long getStartTime() {
   1.665 +		long Result = 0;
   1.666 +		Property prop;
   1.667 +		/*
   1.668 +		 * DTSTART;TZID=Europe/Berlin:20120425T080000
   1.669 +		 * DTSTART;TZID=(GMT+01.00) Sarajevo/Warsaw/Zagreb:20120305T104500
   1.670 +		 * DTSTART:20120308T093000Z
   1.671 +		 * DTSTART;VALUE=DATE:20120709
   1.672 +		 * DTSTART;TZID=Europe/Berlin:20130330T100000
   1.673 +		 */
   1.674 +
   1.675 +		prop = calendarComponent.getProperty(Property.DTSTART);
   1.676 +		if (prop != null) {
   1.677 +			Parameter propTZ = prop.getParameter(Property.TZID);
   1.678 +			if (propTZ != null)
   1.679 +				mstrTimeZoneStart = propTZ.getValue();
   1.680 +			Result = getTimestamp(prop);
   1.681 +		}
   1.682 +		
   1.683 +		return Result;
   1.684 +	}
   1.685 +
   1.686 +	private long getEndTime() {
   1.687 +		long Result = 0;
   1.688 +		Property propDtEnd;
   1.689 +		Property propDuration;
   1.690 +		
   1.691 +		propDtEnd = calendarComponent.getProperty(Property.DTEND);
   1.692 +		propDuration = calendarComponent.getProperty(Property.DURATION);
   1.693 +		if (propDtEnd != null) {
   1.694 +			Parameter propTZ = propDtEnd.getParameter(Property.TZID);
   1.695 +			if (propTZ != null)
   1.696 +				mstrTimeZoneEnd = propTZ.getValue();
   1.697 +			Result = getTimestamp(propDtEnd);
   1.698 +
   1.699 +		} else if (propDuration != null) {
   1.700 +			Result = 0;
   1.701 +			long Start = this.getStartTime();
   1.702 +			String strDuration = propDuration.getValue();
   1.703 +			Dur dur = new Dur(strDuration);
   1.704 +			Result = Start 
   1.705 +					+ dur.getSeconds() 	* 1000 
   1.706 +					+ dur.getMinutes() 	* 60 * 1000 
   1.707 +					+ dur.getHours() 	* 60 * 60 * 1000 
   1.708 +					+ dur.getDays() 	* 60 * 60 * 24 * 1000;
   1.709 +			
   1.710 +			mstrTimeZoneEnd = mstrTimeZoneStart;
   1.711 +		}
   1.712 +
   1.713 +		
   1.714 +		return Result;
   1.715 +	}
   1.716 +	
   1.717 +	private String getTimeZoneStart() {
   1.718 +		String Result = "GMT";
   1.719 +		
   1.720 +		if (!mstrTimeZoneStart.equals("")) {
   1.721 +			Result = mstrTimeZoneStart;
   1.722 +		}
   1.723 +		
   1.724 +		return Result;
   1.725 +	}
   1.726 +
   1.727 +	private String getTimeZoneEnd() {
   1.728 +		String Result = "GMT";
   1.729 +		
   1.730 +		if (!mstrTimeZoneEnd.equals("")) {
   1.731 +			Result = mstrTimeZoneEnd;
   1.732 +		}
   1.733 +		
   1.734 +		return Result;
   1.735 +	}
   1.736 +
   1.737 +	
   1.738 +	private String getDuration() {
   1.739 +		String Result = "";
   1.740 +		Property prop = calendarComponent.getProperty("DURATION");
   1.741 +		
   1.742 +		if (prop != null) {
   1.743 +			//DURATION:PT1H
   1.744 +			Result = prop.getValue();
   1.745 +		} else {
   1.746 +			// no DURATION given by this event. we have to calculate it by ourself
   1.747 +			Result = "P";
   1.748 +			long Start = this.getStartTime();
   1.749 +			long End   = this.getEndTime();
   1.750 +			long Duration = 0;
   1.751 +			if (End != 0)
   1.752 +				Duration = (End - Start) / 1000; // get rid of the milliseconds, they cann't be described with RFC2445-Duration
   1.753 +			
   1.754 +			if (Duration < 0) {
   1.755 +				Duration = 0;
   1.756 +			}
   1.757 +			int Days = (int) Math.ceil(Duration / 24 / 60 / 60);
   1.758 +			int Hours = (int) Math.ceil((Duration - (Days * 24 * 60 * 60)) / 60 / 60);
   1.759 +			int Minutes = (int) Math.ceil((Duration - (Days * 24 * 60 * 60) - (Hours * 60 * 60)) / 60);
   1.760 +			int Seconds = (int) (Duration - (Days * 24 * 60 * 60) - (Hours * 60 * 60) - (Minutes * 60));
   1.761 +		
   1.762 +			if (Days > 0)
   1.763 +				Result += String.valueOf(Days) + "D";
   1.764 +			
   1.765 +			if (!mAllDay) {
   1.766 +				//if a ALL_DAY event occurs, there is no need for hours, minutes and seconds (Android doesn't understand them)
   1.767 +				Result += "T";
   1.768 +				Result += String.valueOf(Hours) + "H";
   1.769 +				Result += String.valueOf(Minutes) + "M";
   1.770 +				Result += String.valueOf(Seconds) + "S";
   1.771 +			}
   1.772 +		}
   1.773 +		
   1.774 +		return Result;
   1.775 +	}
   1.776 +	
   1.777 +	private int getAllDay() {
   1.778 +		int Result = 0;
   1.779 +
   1.780 +		if (mAllDay)
   1.781 +			Result = 1;
   1.782 +		
   1.783 +		return Result;
   1.784 +	}
   1.785 +
   1.786 +	/**
   1.787 +	 * opens the first items of the event
   1.788 +	 * @return success of this function
   1.789 +	 * @see AndroidEvent#createIcs()
   1.790 +	 * @see CalendarEvent#fetchBody()
   1.791 +	 * @throws CaldavProtocolException
   1.792 +	 * @throws IOException
   1.793 +	 * @throws ParserException
   1.794 +	 */
   1.795 +	private boolean parseIcs() throws CaldavProtocolException, IOException, ParserException {
   1.796 +		boolean Error = false;
   1.797 +		
   1.798 +		CalendarBuilder builder = new CalendarBuilder();
   1.799 +		CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_UNFOLDING, true);
   1.800 +		CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING, true);
   1.801 +		CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION, true);
   1.802 +		CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_OUTLOOK_COMPATIBILITY, true);
   1.803 +
   1.804 +		StringReader reader = new StringReader(this.stringIcs);
   1.805 +		try {
   1.806 +			this.calendar = builder.build(reader);
   1.807 +		} catch (ParserException ex) {
   1.808 +			// ical4j fails with this: "Cannot set timezone for UTC properties"
   1.809 +			// CREATED;TZID=America/New_York:20130129T140250
   1.810 +			Error = true;
   1.811 +		}
   1.812 +		
   1.813 +		if (!Error) {
   1.814 +			ComponentList components = null;
   1.815 +			components = this.calendar.getComponents(Component.VEVENT);
   1.816 +			if (components.size() == 0) {
   1.817 +				components = this.calendar.getComponents(Component.VTODO);
   1.818 +				if (components.size() == 0) {
   1.819 +					throw new CaldavProtocolException("unknown events in ICS");
   1.820 +				} else {
   1.821 +					Log.e(TAG, "unsupported event TODO in ICS");
   1.822 +					Error = true;
   1.823 +				}
   1.824 +			} else if (components.size() > 1) {
   1.825 +				Log.e(TAG, "Several events in ICS -> only first will be processed");
   1.826 +			}
   1.827 +	
   1.828 +			// get the TimeZone information
   1.829 +			Component mCom = this.calendar.getComponent(Component.VTIMEZONE);
   1.830 +			if (mCom != null)
   1.831 +				mVTimeZone = (VTimeZone) this.calendar.getComponent(Component.VTIMEZONE);
   1.832 +			if (mVTimeZone != null)
   1.833 +				mTimeZone = new TimeZone(mVTimeZone);
   1.834 +	
   1.835 +			if (!Error)
   1.836 +				calendarComponent = (Component) components.get(0);
   1.837 +		}
   1.838 +			 
   1.839 +		return !Error;
   1.840 +	}
   1.841 +
   1.842 +	/**
   1.843 +	 * searches for an android event
   1.844 +	 * @param androidCalendar
   1.845 +	 * @return the android event
   1.846 +	 * @throws RemoteException
   1.847 +	 */
   1.848 +	public AndroidEvent getAndroidEvent(DavCalendar androidCalendar) throws RemoteException {
   1.849 +		boolean Error = false;
   1.850 +		Uri uriEvents = Events.CONTENT_URI;
   1.851 +		Uri uriAttendee = Attendees.CONTENT_URI;
   1.852 +		Uri uriReminder = Reminders.CONTENT_URI;
   1.853 +		AndroidEvent androidEvent = null;
   1.854 +		
   1.855 +		String selection = "(" + Events._SYNC_ID + " = ?)";
   1.856 +		String[] selectionArgs = new String[] {this.getUri().toString()}; 
   1.857 +		Cursor curEvent = this.mProvider.query(uriEvents, null, selection, selectionArgs, null);
   1.858 +		
   1.859 +		Cursor curAttendee = null;
   1.860 +		Cursor curReminder = null;
   1.861 +		
   1.862 +		if (curEvent == null) {
   1.863 +			Error = true;
   1.864 +		}
   1.865 +		if (!Error) {
   1.866 +			if (curEvent.getCount() == 0) {
   1.867 +				Error = true;
   1.868 +			}
   1.869 +		}
   1.870 +		if (!Error) {
   1.871 +			curEvent.moveToNext();
   1.872 +		
   1.873 +			long EventID = curEvent.getLong(curEvent.getColumnIndex(Events._ID));
   1.874 +			Uri returnedUri = ContentUris.withAppendedId(uriEvents, EventID);
   1.875 +			
   1.876 +			//androidEvent = new AndroidEvent(this.mAccount, this.mProvider, returnedUri, androidCalendar.getAndroidCalendarUri());
   1.877 +			androidEvent = new AndroidEvent(returnedUri, androidCalendar.getAndroidCalendarUri());
   1.878 +			androidEvent.readContentValues(curEvent);
   1.879 +			
   1.880 +			selection = "(" + Attendees.EVENT_ID + " = ?)";
   1.881 +			selectionArgs = new String[] {String.valueOf(EventID)}; 
   1.882 +			curAttendee = this.mProvider.query(uriAttendee, null, selection, selectionArgs, null);
   1.883 +			selection = "(" + Reminders.EVENT_ID + " = ?)";
   1.884 +			selectionArgs = new String[] {String.valueOf(EventID)}; 
   1.885 +			curReminder = this.mProvider.query(uriReminder, null, selection, selectionArgs, null);
   1.886 +			androidEvent.readAttendees(curAttendee);
   1.887 +			androidEvent.readReminder(curReminder);
   1.888 +			curAttendee.close();
   1.889 +			curReminder.close();
   1.890 +		}
   1.891 +		curEvent.close();
   1.892 +		
   1.893 +		return androidEvent;
   1.894 +	}
   1.895 +	
   1.896 +	/**
   1.897 +	 * creates a new androidEvent from a given calendarEvent
   1.898 +	 * @param androidCalendar
   1.899 +	 * @return
   1.900 +	 * @throws ClientProtocolException
   1.901 +	 * @throws IOException
   1.902 +	 * @throws CaldavProtocolException
   1.903 +	 * @throws RemoteException
   1.904 +	 * @throws ParserException
   1.905 +	 * @see {@link SyncAdapter#synchroniseEvents(CaldavFacade, Account, ContentProviderClient, Uri, DavCalendar, SyncStats)}
   1.906 +	 */
   1.907 +	public boolean createAndroidEvent(DavCalendar androidCalendar) throws ClientProtocolException, IOException, CaldavProtocolException, RemoteException, ParserException {
   1.908 +		boolean Result = false;
   1.909 +		boolean BodyFetched = this.fetchBody();
   1.910 +		int CountAttendees = 0;
   1.911 +		int CountReminders = 0;
   1.912 +		
   1.913 +		if (BodyFetched) {
   1.914 +			//calendarEvent.readContentValues(calendarUri);
   1.915 +			this.readContentValues();
   1.916 +			this.setAndroidCalendarId(ContentUris.parseId(androidCalendar.getAndroidCalendarUri()));
   1.917 +		
   1.918 +			Uri uri = this.mProvider.insert(asSyncAdapter(Events.CONTENT_URI, this.mAccount.name, this.mAccount.type), this.ContentValues);
   1.919 +			this.setAndroidEventUri(uri);
   1.920 +		
   1.921 +			Log.d(TAG, "Creating calendar event for " + uri.toString());
   1.922 +			
   1.923 +			//check the attendees
   1.924 +			java.util.ArrayList<ContentValues> AttendeeList = this.getAttandees();
   1.925 +			for (ContentValues Attendee : AttendeeList) {
   1.926 +				this.mProvider.insert(Attendees.CONTENT_URI, Attendee);
   1.927 +				CountAttendees += 1;
   1.928 +			}
   1.929 +			
   1.930 +			//check the reminders
   1.931 +			java.util.ArrayList<ContentValues> ReminderList = this.getReminders();
   1.932 +			for (ContentValues Reminder : ReminderList) {
   1.933 +				this.mProvider.insert(Reminders.CONTENT_URI, Reminder);
   1.934 +				CountReminders += 1;
   1.935 +			}
   1.936 +			
   1.937 +			if ((CountAttendees > 0) || (CountReminders > 0)) {
   1.938 +				//the events gets dirty when attendees or reminders were added
   1.939 +				AndroidEvent androidEvent = this.getAndroidEvent(androidCalendar);
   1.940 +				
   1.941 +				androidEvent.ContentValues.put(Events.DIRTY, 0);
   1.942 +				int RowCount = this.mProvider.update(asSyncAdapter(androidEvent.getUri(), this.mAccount.name, this.mAccount.type), androidEvent.ContentValues, null, null);
   1.943 +				Result = (RowCount == 1);
   1.944 +			} else {
   1.945 +				Result = true;
   1.946 +			}
   1.947 +			
   1.948 +			
   1.949 +		}
   1.950 +		return Result;
   1.951 +	}
   1.952 +	
   1.953 +	/**
   1.954 +	 * the android event is getting updated
   1.955 +	 * @param provider
   1.956 +	 * @param account
   1.957 +	 * @param androidEvent
   1.958 +	 * @param calendarEvent
   1.959 +	 * @return
   1.960 +	 * @throws ClientProtocolException
   1.961 +	 * @throws IOException
   1.962 +	 * @throws CaldavProtocolException
   1.963 +	 * @throws RemoteException
   1.964 +	 * @throws ParserException
   1.965 +	 * @see {@link SyncAdapter#synchroniseEvents(CaldavFacade, Account, ContentProviderClient, Uri, Calendar, SyncStats)}
   1.966 +	 */
   1.967 +	public boolean updateAndroidEvent(AndroidEvent androidEvent) throws ClientProtocolException, IOException, CaldavProtocolException, RemoteException, ParserException {
   1.968 +		boolean BodyFetched = this.fetchBody();
   1.969 +		int Rows = 0;
   1.970 +		
   1.971 +		if (BodyFetched) {
   1.972 +			this.readContentValues();
   1.973 +			this.setAndroidCalendarId(androidEvent.getAndroidCalendarId());
   1.974 +			this.setAndroidEventUri(androidEvent.getUri());
   1.975 +		
   1.976 +			Log.d(TAG, "AndroidEvent is dirty: " + androidEvent.ContentValues.getAsString(Events.DIRTY));
   1.977 +			
   1.978 +			if (androidEvent.checkEventValuesChanged(this.ContentValues)) {
   1.979 +				// just set the raw data from server event into android event
   1.980 +				if (androidEvent.ContentValues.containsKey(Event.RAWDATA))
   1.981 +					androidEvent.ContentValues.remove(Event.RAWDATA);
   1.982 +				androidEvent.ContentValues.put(Event.RAWDATA, this.ContentValues.getAsString(Event.RAWDATA));
   1.983 +				
   1.984 +				//update the attendees and reminders
   1.985 +				this.updateAndroidAttendees();
   1.986 +				this.updateAndroidReminder();
   1.987 +
   1.988 +				androidEvent.ContentValues.put(Events.DIRTY, 0); // the event is now in sync
   1.989 +				Log.d(TAG, "Update calendar event: for "+androidEvent.getUri());
   1.990 +				
   1.991 +				Rows = mProvider.update(asSyncAdapter(androidEvent.getUri(), mAccount.name, mAccount.type), androidEvent.ContentValues, null, null);
   1.992 +				//Log.i(TAG, "Updated calendar event: rows effected " + Rows.toString());
   1.993 +			} else {
   1.994 +				Log.d(TAG, "Update calendar event not needed: for "+androidEvent.getUri());
   1.995 +			}
   1.996 +		}
   1.997 +		return (Rows == 1);
   1.998 +	}
   1.999 +	
  1.1000 +	/**
  1.1001 +	 * updates the attendees from a calendarEvent to its androidEvent.
  1.1002 +	 * the calendarEvent has to know its androidEvent via {@link CalendarEvent#setAndroidEventUri(Uri)}
  1.1003 +	 * @param provider
  1.1004 +	 * @return
  1.1005 +	 * @see SyncAdapter#updateAndroidEvent(ContentProviderClient, Account, AndroidEvent, CalendarEvent)
  1.1006 +	 */
  1.1007 +	private boolean updateAndroidAttendees() {
  1.1008 +		boolean Result = false;
  1.1009 +		
  1.1010 +		try {
  1.1011 +			String mSelectionClause = "(" + Attendees.EVENT_ID + " = ?)";
  1.1012 +			String[] mSelectionArgs = {Long.toString(ContentUris.parseId(this.getAndroidEventUri())) };
  1.1013 +			int RowDelete;
  1.1014 +			RowDelete = this.mProvider.delete(Attendees.CONTENT_URI, mSelectionClause, mSelectionArgs);
  1.1015 +			Log.d(TAG, "Attendees Deleted:" + String.valueOf(RowDelete));
  1.1016 +			
  1.1017 +			java.util.ArrayList<ContentValues> AttendeeList = this.getAttandees();
  1.1018 +			for (ContentValues Attendee : AttendeeList) {
  1.1019 +				this.mProvider.insert(Attendees.CONTENT_URI, Attendee);
  1.1020 +			}
  1.1021 +			Log.d(TAG, "Attendees Inserted:" + String.valueOf(AttendeeList.size()));
  1.1022 +			Result = true;
  1.1023 +		} catch (RemoteException e) {
  1.1024 +			e.printStackTrace();
  1.1025 +		}
  1.1026 +		
  1.1027 +		return Result;
  1.1028 +	}
  1.1029 +	
  1.1030 +	/**
  1.1031 +	 * update the reminders from a calendarEvent to its androidEvent.
  1.1032 +	 * the calendarEvent has to know its androidEvent via {@link CalendarEvent#setAndroidEventUri(Uri)}
  1.1033 +	 * @param provider
  1.1034 +	 * @return
  1.1035 +	 * @see SyncAdapter#updateAndroidEvent(ContentProviderClient, Account, AndroidEvent, CalendarEvent)
  1.1036 +	 */
  1.1037 +	private boolean updateAndroidReminder() {
  1.1038 +		boolean Result = false;
  1.1039 +		
  1.1040 +		try {
  1.1041 +			String mSelectionClause = "(" + Reminders.EVENT_ID + " = ?)";
  1.1042 +			String[] mSelectionArgs = {Long.toString(ContentUris.parseId(this.getAndroidEventUri())) };
  1.1043 +			int RowDelete;
  1.1044 +			RowDelete = this.mProvider.delete(Reminders.CONTENT_URI, mSelectionClause, mSelectionArgs);
  1.1045 +			Log.d(TAG, "Reminders Deleted:" + String.valueOf(RowDelete));
  1.1046 +			
  1.1047 +			
  1.1048 +			Uri ReminderUri;
  1.1049 +			java.util.ArrayList<ContentValues> ReminderList = this.getReminders();
  1.1050 +			for (ContentValues Reminder : ReminderList) {
  1.1051 +				ReminderUri = this.mProvider.insert(Reminders.CONTENT_URI, Reminder);
  1.1052 +				System.out.println(ReminderUri);
  1.1053 +			}
  1.1054 +			Log.d(TAG, "Reminders Inserted:" + String.valueOf(ReminderList.size()));
  1.1055 +			
  1.1056 +			Result = true;
  1.1057 +		} catch (RemoteException e) {
  1.1058 +			e.printStackTrace();
  1.1059 +		}
  1.1060 +		
  1.1061 +		return Result;
  1.1062 +	}
  1.1063 +	
  1.1064 +	private static Uri asSyncAdapter(Uri uri, String account, String accountType) {
  1.1065 +	    return uri.buildUpon()
  1.1066 +	        .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
  1.1067 +	        .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
  1.1068 +	        .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
  1.1069 +	 }
  1.1070 +}
  1.1071 +

mercurial