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

Tue, 10 Feb 2015 18:12:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 10 Feb 2015 18:12:00 +0100
changeset 0
fb9019fb1bf7
permissions
-rw-r--r--

Import initial revisions of existing project AndroidCaldavSyncAdapater,
forked from upstream repository at 27e8a0f8495c92e0780d450bdf0c7cec77a03a55.

michael@0 1 /**
michael@0 2 * Copyright (c) 2012-2013, Gerald Garcia, Timo Berger
michael@0 3 *
michael@0 4 * This file is part of Andoid Caldav Sync Adapter Free.
michael@0 5 *
michael@0 6 * Andoid Caldav Sync Adapter Free is free software: you can redistribute
michael@0 7 * it and/or modify it under the terms of the GNU General Public License
michael@0 8 * as published by the Free Software Foundation, either version 3 of the
michael@0 9 * License, or at your option any later version.
michael@0 10 *
michael@0 11 * Andoid Caldav Sync Adapter Free is distributed in the hope that
michael@0 12 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
michael@0 13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
michael@0 14 * GNU General Public License for more details.
michael@0 15 *
michael@0 16 * You should have received a copy of the GNU General Public License
michael@0 17 * along with Andoid Caldav Sync Adapter Free.
michael@0 18 * If not, see <http://www.gnu.org/licenses/>.
michael@0 19 *
michael@0 20 */
michael@0 21
michael@0 22 package org.gege.caldavsyncadapter.caldav.entities;
michael@0 23
michael@0 24 import java.io.IOException;
michael@0 25 import java.io.StringReader;
michael@0 26 import java.io.UnsupportedEncodingException;
michael@0 27 import java.net.URI;
michael@0 28 import java.net.URL;
michael@0 29 import java.net.URLDecoder;
michael@0 30 import java.text.ParseException;
michael@0 31 import java.util.ArrayList;
michael@0 32
michael@0 33 import javax.xml.parsers.ParserConfigurationException;
michael@0 34 import javax.xml.parsers.SAXParser;
michael@0 35 import javax.xml.parsers.SAXParserFactory;
michael@0 36
michael@0 37 import net.fortuna.ical4j.data.CalendarBuilder;
michael@0 38 import net.fortuna.ical4j.data.ParserException;
michael@0 39 import net.fortuna.ical4j.model.Calendar;
michael@0 40 import net.fortuna.ical4j.model.Component;
michael@0 41 import net.fortuna.ical4j.model.ComponentList;
michael@0 42 import net.fortuna.ical4j.model.DateTime;
michael@0 43 import net.fortuna.ical4j.model.Dur;
michael@0 44 import net.fortuna.ical4j.model.Parameter;
michael@0 45 import net.fortuna.ical4j.model.ParameterList;
michael@0 46 import net.fortuna.ical4j.model.Property;
michael@0 47 import net.fortuna.ical4j.model.PropertyList;
michael@0 48 import net.fortuna.ical4j.model.TimeZone;
michael@0 49 import net.fortuna.ical4j.model.component.VEvent;
michael@0 50 import net.fortuna.ical4j.model.component.VTimeZone;
michael@0 51 import net.fortuna.ical4j.model.parameter.Cn;
michael@0 52 import net.fortuna.ical4j.model.parameter.CuType;
michael@0 53 import net.fortuna.ical4j.model.parameter.PartStat;
michael@0 54 import net.fortuna.ical4j.model.parameter.Role;
michael@0 55 import net.fortuna.ical4j.model.property.Clazz;
michael@0 56 import net.fortuna.ical4j.model.property.Status;
michael@0 57 import net.fortuna.ical4j.util.CompatibilityHints;
michael@0 58
michael@0 59 import org.apache.http.client.ClientProtocolException;
michael@0 60 import org.gege.caldavsyncadapter.Event;
michael@0 61 import org.gege.caldavsyncadapter.android.entities.AndroidEvent;
michael@0 62 import org.gege.caldavsyncadapter.caldav.CaldavFacade;
michael@0 63 import org.gege.caldavsyncadapter.caldav.CaldavProtocolException;
michael@0 64 import org.gege.caldavsyncadapter.caldav.xml.MultiStatusHandler;
michael@0 65 import org.gege.caldavsyncadapter.caldav.xml.sax.MultiStatus;
michael@0 66 import org.gege.caldavsyncadapter.caldav.xml.sax.Prop;
michael@0 67 import org.gege.caldavsyncadapter.caldav.xml.sax.PropStat;
michael@0 68 import org.gege.caldavsyncadapter.caldav.xml.sax.Response;
michael@0 69 import org.gege.caldavsyncadapter.syncadapter.SyncAdapter;
michael@0 70 import org.xml.sax.InputSource;
michael@0 71 import org.xml.sax.SAXException;
michael@0 72 import org.xml.sax.XMLReader;
michael@0 73
michael@0 74 import android.accounts.Account;
michael@0 75 import android.content.ContentProviderClient;
michael@0 76 import android.content.ContentUris;
michael@0 77 import android.content.ContentValues;
michael@0 78 import android.content.SyncStats;
michael@0 79 import android.database.Cursor;
michael@0 80 import android.net.Uri;
michael@0 81 import android.os.RemoteException;
michael@0 82 import android.provider.CalendarContract.Attendees;
michael@0 83 import android.provider.CalendarContract.Calendars;
michael@0 84 import android.provider.CalendarContract.Events;
michael@0 85 import android.provider.CalendarContract.Reminders;
michael@0 86 import android.util.Log;
michael@0 87
michael@0 88
michael@0 89
michael@0 90 public class CalendarEvent extends org.gege.caldavsyncadapter.Event {
michael@0 91 private static final String TAG = "CalendarEvent";
michael@0 92
michael@0 93 private String stringIcs;
michael@0 94
michael@0 95 private Calendar calendar;
michael@0 96
michael@0 97 private Component calendarComponent;
michael@0 98
michael@0 99 private String eTag;
michael@0 100 private URI muri;
michael@0 101 private Uri mAndroidEventUri;
michael@0 102 public URL calendarURL;
michael@0 103
michael@0 104 private boolean mAllDay = false;
michael@0 105 private VTimeZone mVTimeZone = null;
michael@0 106 private TimeZone mTimeZone = null;
michael@0 107
michael@0 108 private String mstrTimeZoneStart = "";
michael@0 109 private String mstrTimeZoneEnd = "";
michael@0 110
michael@0 111 private Account mAccount = null;
michael@0 112 private ContentProviderClient mProvider = null;
michael@0 113
michael@0 114 public CalendarEvent(Account account, ContentProviderClient provider) {
michael@0 115 this.mAccount = account;
michael@0 116 this.mProvider = provider;
michael@0 117 }
michael@0 118
michael@0 119 public String getETag() {
michael@0 120 return eTag;
michael@0 121 }
michael@0 122
michael@0 123 public void setETag(String eTag) {
michael@0 124 this.eTag = eTag;
michael@0 125 }
michael@0 126
michael@0 127 public URI getUri() {
michael@0 128 return muri;
michael@0 129 }
michael@0 130
michael@0 131 public void setUri(URI uri) {
michael@0 132 this.muri = uri;
michael@0 133 }
michael@0 134
michael@0 135 public void setICSasString(String ics) {
michael@0 136 this.stringIcs = ics;
michael@0 137 }
michael@0 138
michael@0 139 public boolean setICSasMultiStatus(String stringMultiStatus) {
michael@0 140 boolean Result = false;
michael@0 141 String ics = "";
michael@0 142 MultiStatus multistatus;
michael@0 143 ArrayList<Response> responselist;
michael@0 144 Response response;
michael@0 145 PropStat propstat;
michael@0 146 Prop prop;
michael@0 147 try {
michael@0 148 SAXParserFactory factory = SAXParserFactory.newInstance();
michael@0 149 SAXParser parser = factory.newSAXParser();
michael@0 150 XMLReader reader = parser.getXMLReader();
michael@0 151 MultiStatusHandler contentHandler = new MultiStatusHandler();
michael@0 152 reader.setContentHandler(contentHandler);
michael@0 153 reader.parse(new InputSource(new StringReader(stringMultiStatus)));
michael@0 154
michael@0 155 multistatus = contentHandler.mMultiStatus;
michael@0 156 if (multistatus != null) {
michael@0 157 responselist = multistatus.ResponseList;
michael@0 158 if (responselist.size() == 1) {
michael@0 159 response = responselist.get(0);
michael@0 160 //HINT: bugfix for google calendar, zimbra replace("@", "%40")
michael@0 161 if (response.href.replace("@", "%40").equals(this.getUri().getRawPath().replace("@", "%40"))) {
michael@0 162 propstat = response.propstat;
michael@0 163 if (propstat != null) {
michael@0 164 if (propstat.status.contains("200 OK")) {
michael@0 165 prop = propstat.prop;
michael@0 166 ics = prop.calendardata;
michael@0 167 this.setETag(prop.getetag);
michael@0 168 Result = true;
michael@0 169 }
michael@0 170 }
michael@0 171 }
michael@0 172 }
michael@0 173 }
michael@0 174 } catch (ParserConfigurationException e1) {
michael@0 175 e1.printStackTrace();
michael@0 176 } catch (SAXException e1) {
michael@0 177 e1.printStackTrace();
michael@0 178 } catch (IOException e) {
michael@0 179 e.printStackTrace();
michael@0 180 }
michael@0 181
michael@0 182 this.stringIcs = ics;
michael@0 183 return Result;
michael@0 184 }
michael@0 185
michael@0 186 /**
michael@0 187 * sets the Uri of the android event
michael@0 188 * @param uri
michael@0 189 * @see org.gege.caldavsyncadapter.syncadapter.SyncAdapter#createAndroidEvent(ContentProviderClient provider, Account account, Uri calendarUri, CalendarEvent calendarEvent)
michael@0 190 * @see org.gege.caldavsyncadapter.syncadapter.SyncAdapter#updateAndroidEvent(ContentProviderClient provider, Account account, AndroidEvent androidEvent, CalendarEvent calendarEvent)
michael@0 191 */
michael@0 192 public void setAndroidEventUri(Uri uri) {
michael@0 193 mAndroidEventUri = uri;
michael@0 194 }
michael@0 195
michael@0 196 /**
michael@0 197 * gets the Uri of the android event
michael@0 198 * @return
michael@0 199 */
michael@0 200 public Uri getAndroidEventUri() {
michael@0 201 return mAndroidEventUri;
michael@0 202 }
michael@0 203
michael@0 204
michael@0 205 /**
michael@0 206 * reads all ContentValues from the caldav source
michael@0 207 * @param calendarUri
michael@0 208 * @return
michael@0 209 * @see org.gege.caldavsyncadapter.syncadapter.SyncAdapter#createAndroidEvent(ContentProviderClient provider, Account account, Uri calendarUri, CalendarEvent calendarEvent)
michael@0 210 * @see org.gege.caldavsyncadapter.syncadapter.SyncAdapter#updateAndroidEvent(ContentProviderClient provider, Account account, AndroidEvent androidEvent, CalendarEvent calendarEvent)
michael@0 211 */
michael@0 212 public boolean readContentValues() {
michael@0 213 this.ContentValues.put(Events.DTSTART, this.getStartTime());
michael@0 214 this.ContentValues.put(Events.EVENT_TIMEZONE, this.getTimeZoneStart());
michael@0 215
michael@0 216 //if (this.getRRule().isEmpty() && this.getRDate().isEmpty()) {
michael@0 217 if (this.getRRule() == null && this.getRDate() == null) {
michael@0 218 //if (AllDay.equals(1)) //{
michael@0 219 // values.put(Events.ALL_DAY, AllDay);
michael@0 220 //} else {
michael@0 221 this.ContentValues.put(Events.DTEND, this.getEndTime());
michael@0 222 this.ContentValues.put(Events.EVENT_END_TIMEZONE, this.getTimeZoneEnd());
michael@0 223 //}
michael@0 224 } else {
michael@0 225 //if (AllDay.equals(1))
michael@0 226 // values.put(Events.ALL_DAY, AllDay);
michael@0 227 this.ContentValues.put(Events.DURATION, this.getDuration());
michael@0 228 }
michael@0 229 int AllDay = this.getAllDay();
michael@0 230 this.ContentValues.put(Events.ALL_DAY, AllDay);
michael@0 231
michael@0 232 this.ContentValues.put(Events.TITLE, this.getTitle());
michael@0 233 //this.ContentValues.put(Events.CALENDAR_ID, ContentUris.parseId(calendarUri));
michael@0 234 this.ContentValues.put(Events._SYNC_ID, this.getUri().toString());
michael@0 235 this.ContentValues.put(ETAG, this.getETag());
michael@0 236 this.ContentValues.put(Events.DESCRIPTION, this.getDescription());
michael@0 237 this.ContentValues.put(Events.EVENT_LOCATION, this.getLocation());
michael@0 238 this.ContentValues.put(Events.ACCESS_LEVEL, this.getAccessLevel());
michael@0 239 this.ContentValues.put(Events.STATUS, this.getStatus());
michael@0 240 this.ContentValues.put(Events.RDATE, this.getRDate());
michael@0 241 this.ContentValues.put(Events.RRULE, this.getRRule());
michael@0 242 this.ContentValues.put(Events.EXRULE, this.getExRule());
michael@0 243 this.ContentValues.put(Events.EXDATE, this.getExDate());
michael@0 244 this.ContentValues.put(UID, this.getUid());
michael@0 245 this.ContentValues.put(RAWDATA, this.stringIcs);
michael@0 246
michael@0 247 return true;
michael@0 248 }
michael@0 249
michael@0 250 /**
michael@0 251 * receives a single event and parses its content
michael@0 252 * @return success of this function
michael@0 253 * @see CalendarEvent#parseIcs()
michael@0 254 * @throws ClientProtocolException
michael@0 255 * @throws IOException
michael@0 256 * @throws CaldavProtocolException
michael@0 257 * @throws ParserException
michael@0 258 */
michael@0 259 public boolean fetchBody() throws ClientProtocolException, IOException, CaldavProtocolException, ParserException {
michael@0 260 boolean Error = false;
michael@0 261
michael@0 262 //replaced fetchEvent() with getEvent()
michael@0 263 //CaldavFacade.fetchEvent(this);
michael@0 264 CaldavFacade.getEvent(this);
michael@0 265
michael@0 266 boolean Parse = this.parseIcs();
michael@0 267 if (!Parse)
michael@0 268 Error = true;
michael@0 269
michael@0 270 return !Error;
michael@0 271 }
michael@0 272
michael@0 273 public java.util.ArrayList<ContentValues> getReminders() {
michael@0 274 java.util.ArrayList<ContentValues> Result = new java.util.ArrayList<ContentValues>();
michael@0 275 ContentValues Reminder;
michael@0 276
michael@0 277 /*
michael@0 278 * http://sourceforge.net/tracker/?func=detail&aid=3021704&group_id=107024&atid=646395
michael@0 279 */
michael@0 280
michael@0 281 net.fortuna.ical4j.model.component.VEvent event = (VEvent) this.calendarComponent;
michael@0 282
michael@0 283 //ComponentList ComList = this.calendar.getComponents(Component.VALARM);
michael@0 284 ComponentList ComList = event.getAlarms();
michael@0 285
michael@0 286 if (ComList != null) {
michael@0 287 for (Object objCom : ComList) {
michael@0 288 Component Com = (Component) objCom;
michael@0 289 Reminder = new ContentValues();
michael@0 290
michael@0 291 //Property ACTION = Com.getProperty("ACTION");
michael@0 292 Property TRIGGER = Com.getProperty("TRIGGER");
michael@0 293 if (TRIGGER != null) {
michael@0 294 Dur Duration = new Dur(TRIGGER.getValue());
michael@0 295 //if (ACTION.getValue().equals("DISPLAY"))
michael@0 296
michael@0 297 int intDuration = Duration.getMinutes() + Duration.getHours() * 60 + Duration.getDays() * 60 * 24;
michael@0 298
michael@0 299 Reminder.put(Reminders.EVENT_ID, ContentUris.parseId(mAndroidEventUri));
michael@0 300 Reminder.put(Reminders.METHOD, Reminders.METHOD_ALERT);
michael@0 301 Reminder.put(Reminders.MINUTES, intDuration);
michael@0 302
michael@0 303 Result.add(Reminder);
michael@0 304 }
michael@0 305 }
michael@0 306 }
michael@0 307 return Result;
michael@0 308 }
michael@0 309
michael@0 310 public java.util.ArrayList<ContentValues> getAttandees() {
michael@0 311 java.util.ArrayList<ContentValues> Result = new java.util.ArrayList<ContentValues>();
michael@0 312 ContentValues Attendee;
michael@0 313 PropertyList Propertys = calendarComponent.getProperties(Property.ATTENDEE);
michael@0 314 if (Propertys != null) {
michael@0 315 for (Object objProperty : Propertys){
michael@0 316 Property property = (Property) objProperty;
michael@0 317 Attendee = ReadAttendeeProperties(property,Property.ATTENDEE);
michael@0 318 if (Attendee != null)
michael@0 319 Result.add(Attendee);
michael@0 320 }
michael@0 321 }
michael@0 322 Propertys = calendarComponent.getProperties(Property.ORGANIZER);
michael@0 323 if (Propertys != null) {
michael@0 324 for (Object objProperty : Propertys){
michael@0 325 Property property = (Property) objProperty;
michael@0 326 Attendee = ReadAttendeeProperties(property,Property.ORGANIZER);
michael@0 327 if (Attendee != null)
michael@0 328 Result.add(Attendee);
michael@0 329 }
michael@0 330 }
michael@0 331
michael@0 332
michael@0 333 return Result;
michael@0 334 }
michael@0 335
michael@0 336 private String mstrcIcalPropertyError = "net.fortunal.ical4j.invalid:";
michael@0 337 private ContentValues ReadAttendeeProperties(Property property, String Type) {
michael@0 338 ContentValues Attendee = null;
michael@0 339
michael@0 340 ParameterList Parameters = property.getParameters();
michael@0 341 Parameter CN = Parameters.getParameter(Cn.CN);
michael@0 342 Parameter ROLE = Parameters.getParameter(Role.ROLE);
michael@0 343 Parameter CUTYPE = Parameters.getParameter(CuType.CUTYPE);
michael@0 344 //Parameter RSVP = Parameters.getParameter("RSVP");
michael@0 345 Parameter PARTSTAT = Parameters.getParameter(PartStat.PARTSTAT);
michael@0 346
michael@0 347 String strCN = "";
michael@0 348 String strROLE = "";
michael@0 349 String strCUTYPE = "";
michael@0 350 String strValue = property.getValue().replace("mailto:", "");
michael@0 351 String strPARTSTAT = "";
michael@0 352
michael@0 353 if (strValue.startsWith(mstrcIcalPropertyError)) {
michael@0 354 strValue = strValue.replace(mstrcIcalPropertyError, "");
michael@0 355 try {
michael@0 356 strValue = URLDecoder.decode(strValue, "UTF-8");
michael@0 357 } catch (UnsupportedEncodingException e) {
michael@0 358 e.printStackTrace();
michael@0 359 }
michael@0 360 }
michael@0 361
michael@0 362 if (CN != null)
michael@0 363 strCN = CN.getValue();
michael@0 364 if (ROLE != null)
michael@0 365 strROLE = ROLE.getValue();
michael@0 366 if (CUTYPE != null)
michael@0 367 strCUTYPE = CUTYPE.getValue();
michael@0 368 if (PARTSTAT != null)
michael@0 369 strPARTSTAT = PARTSTAT.getValue();
michael@0 370
michael@0 371 if (strCN.equals("")) {
michael@0 372 if (!strValue.equals("")) {
michael@0 373 strCN = strValue;
michael@0 374 }
michael@0 375 }
michael@0 376
michael@0 377 if (!strCN.equals("")) {
michael@0 378 if (strCUTYPE.equals("") || strCUTYPE.equals("INDIVIDUAL")) {
michael@0 379 Attendee = new ContentValues();
michael@0 380
michael@0 381 Attendee.put(Attendees.EVENT_ID, ContentUris.parseId(mAndroidEventUri));
michael@0 382
michael@0 383 Attendee.put(Attendees.ATTENDEE_NAME, strCN);
michael@0 384 Attendee.put(Attendees.ATTENDEE_EMAIL, strValue);
michael@0 385
michael@0 386 if (strROLE.equals("OPT-PARTICIPANT"))
michael@0 387 Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);
michael@0 388 else if (strROLE.equals("NON-PARTICIPANT"))
michael@0 389 Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_NONE);
michael@0 390 else if (strROLE.equals("REQ-PARTICIPANT"))
michael@0 391 Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_REQUIRED);
michael@0 392 else if (strROLE.equals("CHAIR"))
michael@0 393 Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_REQUIRED);
michael@0 394 else
michael@0 395 Attendee.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_NONE);
michael@0 396
michael@0 397 if (Type.equals(Property.ATTENDEE))
michael@0 398 Attendee.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
michael@0 399 else if (Type.equals(Property.ORGANIZER))
michael@0 400 Attendee.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ORGANIZER);
michael@0 401 else
michael@0 402 Attendee.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_NONE);
michael@0 403
michael@0 404 if (strPARTSTAT.equals(PartStat.NEEDS_ACTION.getValue()))
michael@0 405 Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
michael@0 406 else if (strPARTSTAT.equals(PartStat.ACCEPTED.getValue()))
michael@0 407 Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_ACCEPTED);
michael@0 408 else if (strPARTSTAT.equals(PartStat.DECLINED.getValue()))
michael@0 409 Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_DECLINED);
michael@0 410 else if (strPARTSTAT.equals(PartStat.COMPLETED.getValue()))
michael@0 411 Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_NONE);
michael@0 412 else if (strPARTSTAT.equals(PartStat.TENTATIVE.getValue()))
michael@0 413 Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_TENTATIVE);
michael@0 414 else
michael@0 415 Attendee.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
michael@0 416
michael@0 417 }
michael@0 418 }
michael@0 419
michael@0 420 return Attendee;
michael@0 421 }
michael@0 422
michael@0 423 private long getAccessLevel() {
michael@0 424 long Result = Events.ACCESS_DEFAULT;
michael@0 425 String Value = "";
michael@0 426 Property property = calendarComponent.getProperty(Property.CLASS);
michael@0 427 if (property != null) {
michael@0 428 Value = property.getValue();
michael@0 429 if (Value.equals(Clazz.PUBLIC))
michael@0 430 Result = Events.ACCESS_PUBLIC;
michael@0 431 else if (Value.equals(Clazz.PRIVATE))
michael@0 432 Result = Events.ACCESS_PRIVATE;
michael@0 433 else if (Value.equals(Clazz.CONFIDENTIAL))
michael@0 434 Result = Events.ACCESS_PRIVATE; // should be ACCESS_CONFIDENTIAL, but is not implemented within Android
michael@0 435 }
michael@0 436
michael@0 437 return Result;
michael@0 438 }
michael@0 439
michael@0 440 private int getStatus() {
michael@0 441 int Result = -1;
michael@0 442 String Value = "";
michael@0 443 Property property = calendarComponent.getProperty(Property.STATUS);
michael@0 444 if (property != null) {
michael@0 445 Value = property.getValue();
michael@0 446 if (Value.equals(Status.VEVENT_CONFIRMED.getValue()))
michael@0 447 Result = Events.STATUS_CONFIRMED;
michael@0 448 else if (Value.equals(Status.VEVENT_CANCELLED.getValue()))
michael@0 449 Result = Events.STATUS_CANCELED;
michael@0 450 else if (Value.equals(Status.VEVENT_TENTATIVE.getValue()))
michael@0 451 Result = Events.STATUS_TENTATIVE;
michael@0 452 }
michael@0 453
michael@0 454 return Result;
michael@0 455 }
michael@0 456
michael@0 457 private String getDescription() {
michael@0 458 String Result = null;
michael@0 459 Property property = calendarComponent.getProperty(Property.DESCRIPTION);
michael@0 460 if (property != null)
michael@0 461 Result = property.getValue();
michael@0 462
michael@0 463 return Result;
michael@0 464 }
michael@0 465
michael@0 466 private String getLocation() {
michael@0 467 String Result = null;
michael@0 468 Property property = calendarComponent.getProperty(Property.LOCATION);
michael@0 469 if (property != null)
michael@0 470 Result = property.getValue();
michael@0 471
michael@0 472 return Result;
michael@0 473 }
michael@0 474
michael@0 475 private String getTitle() {
michael@0 476 Property property = calendarComponent.getProperty(Property.SUMMARY);
michael@0 477 if (property != null)
michael@0 478 return property.getValue();
michael@0 479 else
michael@0 480 return "**unkonwn**";
michael@0 481 }
michael@0 482
michael@0 483 private String getRRule() {
michael@0 484 String Result = null;
michael@0 485 Property property = calendarComponent.getProperty(Property.RRULE);
michael@0 486 if (property != null)
michael@0 487 Result = property.getValue();
michael@0 488
michael@0 489 return Result;
michael@0 490 }
michael@0 491
michael@0 492 private String getExRule() {
michael@0 493 String Result = null;
michael@0 494 Property property = calendarComponent.getProperty(Property.EXRULE);
michael@0 495 if (property != null)
michael@0 496 Result = property.getValue();
michael@0 497
michael@0 498 return Result;
michael@0 499 }
michael@0 500
michael@0 501 private String getRDate() {
michael@0 502 String Result = null;
michael@0 503
michael@0 504 java.util.ArrayList<String> ExDates = this.getRDates();
michael@0 505 for (String Value: ExDates) {
michael@0 506 if (Result == null)
michael@0 507 Result = "";
michael@0 508 if (!Result.isEmpty())
michael@0 509 Result += ",";
michael@0 510 Result += Value;
michael@0 511 }
michael@0 512
michael@0 513 return Result;
michael@0 514 }
michael@0 515
michael@0 516 private java.util.ArrayList<String> getRDates() {
michael@0 517 java.util.ArrayList<String> Result = new java.util.ArrayList<String>();
michael@0 518 PropertyList Propertys = calendarComponent.getProperties(Property.RDATE);
michael@0 519 if (Propertys != null) {
michael@0 520 Property property;
michael@0 521 for (Object objProperty : Propertys){
michael@0 522 property = (Property) objProperty;
michael@0 523 Result.add(property.getValue());
michael@0 524 }
michael@0 525 }
michael@0 526
michael@0 527 return Result;
michael@0 528 }
michael@0 529
michael@0 530 private String getExDate() {
michael@0 531 String Result = null;
michael@0 532
michael@0 533 java.util.ArrayList<String> ExDates = this.getExDates();
michael@0 534 for (String Value: ExDates) {
michael@0 535 if (Result == null)
michael@0 536 Result = "";
michael@0 537 if (!Result.isEmpty())
michael@0 538 Result += ",";
michael@0 539 Result += Value;
michael@0 540 }
michael@0 541
michael@0 542 return Result;
michael@0 543 }
michael@0 544
michael@0 545 private java.util.ArrayList<String> getExDates() {
michael@0 546 java.util.ArrayList<String> Result = new java.util.ArrayList<String>();
michael@0 547 PropertyList Propertys = calendarComponent.getProperties(Property.EXDATE);
michael@0 548 if (Propertys != null) {
michael@0 549 Property property;
michael@0 550 for (Object objProperty : Propertys){
michael@0 551 property = (Property) objProperty;
michael@0 552 Result.add(property.getValue());
michael@0 553 }
michael@0 554 }
michael@0 555
michael@0 556 return Result;
michael@0 557 }
michael@0 558
michael@0 559 private String getUid() {
michael@0 560 String Result = "";
michael@0 561 Property prop = calendarComponent.getProperty(Property.UID);
michael@0 562 if (prop != null) {
michael@0 563 Result = prop.getValue();
michael@0 564 }
michael@0 565
michael@0 566 return Result;
michael@0 567 }
michael@0 568
michael@0 569 private Long getTimestamp(Property prop) {
michael@0 570 Long Result = null;
michael@0 571 String strTimeZone = "";
michael@0 572 //TimeZone timeZone = null;
michael@0 573
michael@0 574 try {
michael@0 575 String strDate = prop.getValue();
michael@0 576
michael@0 577 Parameter parAllDay = prop.getParameter("VALUE");
michael@0 578 if (parAllDay != null) {
michael@0 579 if (parAllDay.getValue().equals("DATE")) {
michael@0 580 mAllDay = true;
michael@0 581 strDate += "T000000Z";
michael@0 582 }
michael@0 583 }
michael@0 584
michael@0 585 Parameter propTZ = prop.getParameter(Property.TZID);
michael@0 586 if (propTZ != null)
michael@0 587 strTimeZone = propTZ.getValue();
michael@0 588
michael@0 589 //TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
michael@0 590 //if (!strTimeZone.equals(""))
michael@0 591 // timeZone = registry.getTimeZone(strTimeZone);
michael@0 592
michael@0 593 //if (timeZone != null) {
michael@0 594 if (!strTimeZone.equals("")) {
michael@0 595 //Result = new DateTime(strDate, timeZone);
michael@0 596 //Result1 = Result.getTime();
michael@0 597
michael@0 598 //20130331T120000
michael@0 599 int Year = Integer.parseInt(strDate.substring(0, 4));
michael@0 600 int Month = Integer.parseInt(strDate.substring(4, 6)) - 1;
michael@0 601 int Day = Integer.parseInt(strDate.substring(6, 8));
michael@0 602 int Hour = Integer.parseInt(strDate.substring(9, 11));
michael@0 603 int Minute = Integer.parseInt(strDate.substring(11, 13));
michael@0 604 int Second = Integer.parseInt(strDate.substring(13, 15));
michael@0 605
michael@0 606 // time in UTC
michael@0 607 java.util.TimeZone jtz = java.util.TimeZone.getTimeZone("UTC");
michael@0 608 java.util.Calendar cal = java.util.GregorianCalendar.getInstance(jtz);
michael@0 609 cal.set(Year, Month, Day, Hour, Minute, Second);
michael@0 610 cal.set(java.util.Calendar.MILLISECOND, 0);
michael@0 611 Result = cal.getTimeInMillis();
michael@0 612
michael@0 613 // get the timezone
michael@0 614 String[] IDs = java.util.TimeZone.getAvailableIDs();
michael@0 615 Boolean Found = false;
michael@0 616 for (int i = 0; i < IDs.length; i++) {
michael@0 617 Found = Found || IDs[i].equals(strTimeZone);
michael@0 618 }
michael@0 619 if (Found) {
michael@0 620 jtz = java.util.TimeZone.getTimeZone(strTimeZone);
michael@0 621
michael@0 622 // subtract the offset
michael@0 623 Result -= jtz.getRawOffset();
michael@0 624
michael@0 625 // remove dst
michael@0 626 if (jtz.inDaylightTime(new java.util.Date(Result)))
michael@0 627 Result -= jtz.getDSTSavings();
michael@0 628
michael@0 629 } else {
michael@0 630 if (mTimeZone != null) {
michael@0 631 // subtract the offset
michael@0 632 Result -= mTimeZone.getRawOffset();
michael@0 633
michael@0 634 // remove dst
michael@0 635 if (mTimeZone.inDaylightTime(new java.util.Date(Result)))
michael@0 636 Result -= mTimeZone.getDSTSavings();
michael@0 637 } else {
michael@0 638 // unknown Time?
michael@0 639 // treat as local time, should not happen too often :)
michael@0 640 Result = new DateTime(strDate).getTime();
michael@0 641 }
michael@0 642 }
michael@0 643 } else {
michael@0 644 if (strDate.endsWith("Z")) {
michael@0 645 // GMT or UTC
michael@0 646 Result = new DateTime(strDate).getTime();
michael@0 647 } else {
michael@0 648 // unknown Time?
michael@0 649 // treat as local time, should not happen too often :)
michael@0 650 Result = new DateTime(strDate).getTime();
michael@0 651 }
michael@0 652 }
michael@0 653
michael@0 654 } catch (ParseException e) {
michael@0 655 e.printStackTrace();
michael@0 656 }
michael@0 657
michael@0 658 return Result;
michael@0 659 }
michael@0 660
michael@0 661 private long getStartTime() {
michael@0 662 long Result = 0;
michael@0 663 Property prop;
michael@0 664 /*
michael@0 665 * DTSTART;TZID=Europe/Berlin:20120425T080000
michael@0 666 * DTSTART;TZID=(GMT+01.00) Sarajevo/Warsaw/Zagreb:20120305T104500
michael@0 667 * DTSTART:20120308T093000Z
michael@0 668 * DTSTART;VALUE=DATE:20120709
michael@0 669 * DTSTART;TZID=Europe/Berlin:20130330T100000
michael@0 670 */
michael@0 671
michael@0 672 prop = calendarComponent.getProperty(Property.DTSTART);
michael@0 673 if (prop != null) {
michael@0 674 Parameter propTZ = prop.getParameter(Property.TZID);
michael@0 675 if (propTZ != null)
michael@0 676 mstrTimeZoneStart = propTZ.getValue();
michael@0 677 Result = getTimestamp(prop);
michael@0 678 }
michael@0 679
michael@0 680 return Result;
michael@0 681 }
michael@0 682
michael@0 683 private long getEndTime() {
michael@0 684 long Result = 0;
michael@0 685 Property propDtEnd;
michael@0 686 Property propDuration;
michael@0 687
michael@0 688 propDtEnd = calendarComponent.getProperty(Property.DTEND);
michael@0 689 propDuration = calendarComponent.getProperty(Property.DURATION);
michael@0 690 if (propDtEnd != null) {
michael@0 691 Parameter propTZ = propDtEnd.getParameter(Property.TZID);
michael@0 692 if (propTZ != null)
michael@0 693 mstrTimeZoneEnd = propTZ.getValue();
michael@0 694 Result = getTimestamp(propDtEnd);
michael@0 695
michael@0 696 } else if (propDuration != null) {
michael@0 697 Result = 0;
michael@0 698 long Start = this.getStartTime();
michael@0 699 String strDuration = propDuration.getValue();
michael@0 700 Dur dur = new Dur(strDuration);
michael@0 701 Result = Start
michael@0 702 + dur.getSeconds() * 1000
michael@0 703 + dur.getMinutes() * 60 * 1000
michael@0 704 + dur.getHours() * 60 * 60 * 1000
michael@0 705 + dur.getDays() * 60 * 60 * 24 * 1000;
michael@0 706
michael@0 707 mstrTimeZoneEnd = mstrTimeZoneStart;
michael@0 708 }
michael@0 709
michael@0 710
michael@0 711 return Result;
michael@0 712 }
michael@0 713
michael@0 714 private String getTimeZoneStart() {
michael@0 715 String Result = "GMT";
michael@0 716
michael@0 717 if (!mstrTimeZoneStart.equals("")) {
michael@0 718 Result = mstrTimeZoneStart;
michael@0 719 }
michael@0 720
michael@0 721 return Result;
michael@0 722 }
michael@0 723
michael@0 724 private String getTimeZoneEnd() {
michael@0 725 String Result = "GMT";
michael@0 726
michael@0 727 if (!mstrTimeZoneEnd.equals("")) {
michael@0 728 Result = mstrTimeZoneEnd;
michael@0 729 }
michael@0 730
michael@0 731 return Result;
michael@0 732 }
michael@0 733
michael@0 734
michael@0 735 private String getDuration() {
michael@0 736 String Result = "";
michael@0 737 Property prop = calendarComponent.getProperty("DURATION");
michael@0 738
michael@0 739 if (prop != null) {
michael@0 740 //DURATION:PT1H
michael@0 741 Result = prop.getValue();
michael@0 742 } else {
michael@0 743 // no DURATION given by this event. we have to calculate it by ourself
michael@0 744 Result = "P";
michael@0 745 long Start = this.getStartTime();
michael@0 746 long End = this.getEndTime();
michael@0 747 long Duration = 0;
michael@0 748 if (End != 0)
michael@0 749 Duration = (End - Start) / 1000; // get rid of the milliseconds, they cann't be described with RFC2445-Duration
michael@0 750
michael@0 751 if (Duration < 0) {
michael@0 752 Duration = 0;
michael@0 753 }
michael@0 754 int Days = (int) Math.ceil(Duration / 24 / 60 / 60);
michael@0 755 int Hours = (int) Math.ceil((Duration - (Days * 24 * 60 * 60)) / 60 / 60);
michael@0 756 int Minutes = (int) Math.ceil((Duration - (Days * 24 * 60 * 60) - (Hours * 60 * 60)) / 60);
michael@0 757 int Seconds = (int) (Duration - (Days * 24 * 60 * 60) - (Hours * 60 * 60) - (Minutes * 60));
michael@0 758
michael@0 759 if (Days > 0)
michael@0 760 Result += String.valueOf(Days) + "D";
michael@0 761
michael@0 762 if (!mAllDay) {
michael@0 763 //if a ALL_DAY event occurs, there is no need for hours, minutes and seconds (Android doesn't understand them)
michael@0 764 Result += "T";
michael@0 765 Result += String.valueOf(Hours) + "H";
michael@0 766 Result += String.valueOf(Minutes) + "M";
michael@0 767 Result += String.valueOf(Seconds) + "S";
michael@0 768 }
michael@0 769 }
michael@0 770
michael@0 771 return Result;
michael@0 772 }
michael@0 773
michael@0 774 private int getAllDay() {
michael@0 775 int Result = 0;
michael@0 776
michael@0 777 if (mAllDay)
michael@0 778 Result = 1;
michael@0 779
michael@0 780 return Result;
michael@0 781 }
michael@0 782
michael@0 783 /**
michael@0 784 * opens the first items of the event
michael@0 785 * @return success of this function
michael@0 786 * @see AndroidEvent#createIcs()
michael@0 787 * @see CalendarEvent#fetchBody()
michael@0 788 * @throws CaldavProtocolException
michael@0 789 * @throws IOException
michael@0 790 * @throws ParserException
michael@0 791 */
michael@0 792 private boolean parseIcs() throws CaldavProtocolException, IOException, ParserException {
michael@0 793 boolean Error = false;
michael@0 794
michael@0 795 CalendarBuilder builder = new CalendarBuilder();
michael@0 796 CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_UNFOLDING, true);
michael@0 797 CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING, true);
michael@0 798 CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_RELAXED_VALIDATION, true);
michael@0 799 CompatibilityHints.setHintEnabled(CompatibilityHints.KEY_OUTLOOK_COMPATIBILITY, true);
michael@0 800
michael@0 801 StringReader reader = new StringReader(this.stringIcs);
michael@0 802 try {
michael@0 803 this.calendar = builder.build(reader);
michael@0 804 } catch (ParserException ex) {
michael@0 805 // ical4j fails with this: "Cannot set timezone for UTC properties"
michael@0 806 // CREATED;TZID=America/New_York:20130129T140250
michael@0 807 Error = true;
michael@0 808 }
michael@0 809
michael@0 810 if (!Error) {
michael@0 811 ComponentList components = null;
michael@0 812 components = this.calendar.getComponents(Component.VEVENT);
michael@0 813 if (components.size() == 0) {
michael@0 814 components = this.calendar.getComponents(Component.VTODO);
michael@0 815 if (components.size() == 0) {
michael@0 816 throw new CaldavProtocolException("unknown events in ICS");
michael@0 817 } else {
michael@0 818 Log.e(TAG, "unsupported event TODO in ICS");
michael@0 819 Error = true;
michael@0 820 }
michael@0 821 } else if (components.size() > 1) {
michael@0 822 Log.e(TAG, "Several events in ICS -> only first will be processed");
michael@0 823 }
michael@0 824
michael@0 825 // get the TimeZone information
michael@0 826 Component mCom = this.calendar.getComponent(Component.VTIMEZONE);
michael@0 827 if (mCom != null)
michael@0 828 mVTimeZone = (VTimeZone) this.calendar.getComponent(Component.VTIMEZONE);
michael@0 829 if (mVTimeZone != null)
michael@0 830 mTimeZone = new TimeZone(mVTimeZone);
michael@0 831
michael@0 832 if (!Error)
michael@0 833 calendarComponent = (Component) components.get(0);
michael@0 834 }
michael@0 835
michael@0 836 return !Error;
michael@0 837 }
michael@0 838
michael@0 839 /**
michael@0 840 * searches for an android event
michael@0 841 * @param androidCalendar
michael@0 842 * @return the android event
michael@0 843 * @throws RemoteException
michael@0 844 */
michael@0 845 public AndroidEvent getAndroidEvent(DavCalendar androidCalendar) throws RemoteException {
michael@0 846 boolean Error = false;
michael@0 847 Uri uriEvents = Events.CONTENT_URI;
michael@0 848 Uri uriAttendee = Attendees.CONTENT_URI;
michael@0 849 Uri uriReminder = Reminders.CONTENT_URI;
michael@0 850 AndroidEvent androidEvent = null;
michael@0 851
michael@0 852 String selection = "(" + Events._SYNC_ID + " = ?)";
michael@0 853 String[] selectionArgs = new String[] {this.getUri().toString()};
michael@0 854 Cursor curEvent = this.mProvider.query(uriEvents, null, selection, selectionArgs, null);
michael@0 855
michael@0 856 Cursor curAttendee = null;
michael@0 857 Cursor curReminder = null;
michael@0 858
michael@0 859 if (curEvent == null) {
michael@0 860 Error = true;
michael@0 861 }
michael@0 862 if (!Error) {
michael@0 863 if (curEvent.getCount() == 0) {
michael@0 864 Error = true;
michael@0 865 }
michael@0 866 }
michael@0 867 if (!Error) {
michael@0 868 curEvent.moveToNext();
michael@0 869
michael@0 870 long EventID = curEvent.getLong(curEvent.getColumnIndex(Events._ID));
michael@0 871 Uri returnedUri = ContentUris.withAppendedId(uriEvents, EventID);
michael@0 872
michael@0 873 //androidEvent = new AndroidEvent(this.mAccount, this.mProvider, returnedUri, androidCalendar.getAndroidCalendarUri());
michael@0 874 androidEvent = new AndroidEvent(returnedUri, androidCalendar.getAndroidCalendarUri());
michael@0 875 androidEvent.readContentValues(curEvent);
michael@0 876
michael@0 877 selection = "(" + Attendees.EVENT_ID + " = ?)";
michael@0 878 selectionArgs = new String[] {String.valueOf(EventID)};
michael@0 879 curAttendee = this.mProvider.query(uriAttendee, null, selection, selectionArgs, null);
michael@0 880 selection = "(" + Reminders.EVENT_ID + " = ?)";
michael@0 881 selectionArgs = new String[] {String.valueOf(EventID)};
michael@0 882 curReminder = this.mProvider.query(uriReminder, null, selection, selectionArgs, null);
michael@0 883 androidEvent.readAttendees(curAttendee);
michael@0 884 androidEvent.readReminder(curReminder);
michael@0 885 curAttendee.close();
michael@0 886 curReminder.close();
michael@0 887 }
michael@0 888 curEvent.close();
michael@0 889
michael@0 890 return androidEvent;
michael@0 891 }
michael@0 892
michael@0 893 /**
michael@0 894 * creates a new androidEvent from a given calendarEvent
michael@0 895 * @param androidCalendar
michael@0 896 * @return
michael@0 897 * @throws ClientProtocolException
michael@0 898 * @throws IOException
michael@0 899 * @throws CaldavProtocolException
michael@0 900 * @throws RemoteException
michael@0 901 * @throws ParserException
michael@0 902 * @see {@link SyncAdapter#synchroniseEvents(CaldavFacade, Account, ContentProviderClient, Uri, DavCalendar, SyncStats)}
michael@0 903 */
michael@0 904 public boolean createAndroidEvent(DavCalendar androidCalendar) throws ClientProtocolException, IOException, CaldavProtocolException, RemoteException, ParserException {
michael@0 905 boolean Result = false;
michael@0 906 boolean BodyFetched = this.fetchBody();
michael@0 907 int CountAttendees = 0;
michael@0 908 int CountReminders = 0;
michael@0 909
michael@0 910 if (BodyFetched) {
michael@0 911 //calendarEvent.readContentValues(calendarUri);
michael@0 912 this.readContentValues();
michael@0 913 this.setAndroidCalendarId(ContentUris.parseId(androidCalendar.getAndroidCalendarUri()));
michael@0 914
michael@0 915 Uri uri = this.mProvider.insert(asSyncAdapter(Events.CONTENT_URI, this.mAccount.name, this.mAccount.type), this.ContentValues);
michael@0 916 this.setAndroidEventUri(uri);
michael@0 917
michael@0 918 Log.d(TAG, "Creating calendar event for " + uri.toString());
michael@0 919
michael@0 920 //check the attendees
michael@0 921 java.util.ArrayList<ContentValues> AttendeeList = this.getAttandees();
michael@0 922 for (ContentValues Attendee : AttendeeList) {
michael@0 923 this.mProvider.insert(Attendees.CONTENT_URI, Attendee);
michael@0 924 CountAttendees += 1;
michael@0 925 }
michael@0 926
michael@0 927 //check the reminders
michael@0 928 java.util.ArrayList<ContentValues> ReminderList = this.getReminders();
michael@0 929 for (ContentValues Reminder : ReminderList) {
michael@0 930 this.mProvider.insert(Reminders.CONTENT_URI, Reminder);
michael@0 931 CountReminders += 1;
michael@0 932 }
michael@0 933
michael@0 934 if ((CountAttendees > 0) || (CountReminders > 0)) {
michael@0 935 //the events gets dirty when attendees or reminders were added
michael@0 936 AndroidEvent androidEvent = this.getAndroidEvent(androidCalendar);
michael@0 937
michael@0 938 androidEvent.ContentValues.put(Events.DIRTY, 0);
michael@0 939 int RowCount = this.mProvider.update(asSyncAdapter(androidEvent.getUri(), this.mAccount.name, this.mAccount.type), androidEvent.ContentValues, null, null);
michael@0 940 Result = (RowCount == 1);
michael@0 941 } else {
michael@0 942 Result = true;
michael@0 943 }
michael@0 944
michael@0 945
michael@0 946 }
michael@0 947 return Result;
michael@0 948 }
michael@0 949
michael@0 950 /**
michael@0 951 * the android event is getting updated
michael@0 952 * @param provider
michael@0 953 * @param account
michael@0 954 * @param androidEvent
michael@0 955 * @param calendarEvent
michael@0 956 * @return
michael@0 957 * @throws ClientProtocolException
michael@0 958 * @throws IOException
michael@0 959 * @throws CaldavProtocolException
michael@0 960 * @throws RemoteException
michael@0 961 * @throws ParserException
michael@0 962 * @see {@link SyncAdapter#synchroniseEvents(CaldavFacade, Account, ContentProviderClient, Uri, Calendar, SyncStats)}
michael@0 963 */
michael@0 964 public boolean updateAndroidEvent(AndroidEvent androidEvent) throws ClientProtocolException, IOException, CaldavProtocolException, RemoteException, ParserException {
michael@0 965 boolean BodyFetched = this.fetchBody();
michael@0 966 int Rows = 0;
michael@0 967
michael@0 968 if (BodyFetched) {
michael@0 969 this.readContentValues();
michael@0 970 this.setAndroidCalendarId(androidEvent.getAndroidCalendarId());
michael@0 971 this.setAndroidEventUri(androidEvent.getUri());
michael@0 972
michael@0 973 Log.d(TAG, "AndroidEvent is dirty: " + androidEvent.ContentValues.getAsString(Events.DIRTY));
michael@0 974
michael@0 975 if (androidEvent.checkEventValuesChanged(this.ContentValues)) {
michael@0 976 // just set the raw data from server event into android event
michael@0 977 if (androidEvent.ContentValues.containsKey(Event.RAWDATA))
michael@0 978 androidEvent.ContentValues.remove(Event.RAWDATA);
michael@0 979 androidEvent.ContentValues.put(Event.RAWDATA, this.ContentValues.getAsString(Event.RAWDATA));
michael@0 980
michael@0 981 //update the attendees and reminders
michael@0 982 this.updateAndroidAttendees();
michael@0 983 this.updateAndroidReminder();
michael@0 984
michael@0 985 androidEvent.ContentValues.put(Events.DIRTY, 0); // the event is now in sync
michael@0 986 Log.d(TAG, "Update calendar event: for "+androidEvent.getUri());
michael@0 987
michael@0 988 Rows = mProvider.update(asSyncAdapter(androidEvent.getUri(), mAccount.name, mAccount.type), androidEvent.ContentValues, null, null);
michael@0 989 //Log.i(TAG, "Updated calendar event: rows effected " + Rows.toString());
michael@0 990 } else {
michael@0 991 Log.d(TAG, "Update calendar event not needed: for "+androidEvent.getUri());
michael@0 992 }
michael@0 993 }
michael@0 994 return (Rows == 1);
michael@0 995 }
michael@0 996
michael@0 997 /**
michael@0 998 * updates the attendees from a calendarEvent to its androidEvent.
michael@0 999 * the calendarEvent has to know its androidEvent via {@link CalendarEvent#setAndroidEventUri(Uri)}
michael@0 1000 * @param provider
michael@0 1001 * @return
michael@0 1002 * @see SyncAdapter#updateAndroidEvent(ContentProviderClient, Account, AndroidEvent, CalendarEvent)
michael@0 1003 */
michael@0 1004 private boolean updateAndroidAttendees() {
michael@0 1005 boolean Result = false;
michael@0 1006
michael@0 1007 try {
michael@0 1008 String mSelectionClause = "(" + Attendees.EVENT_ID + " = ?)";
michael@0 1009 String[] mSelectionArgs = {Long.toString(ContentUris.parseId(this.getAndroidEventUri())) };
michael@0 1010 int RowDelete;
michael@0 1011 RowDelete = this.mProvider.delete(Attendees.CONTENT_URI, mSelectionClause, mSelectionArgs);
michael@0 1012 Log.d(TAG, "Attendees Deleted:" + String.valueOf(RowDelete));
michael@0 1013
michael@0 1014 java.util.ArrayList<ContentValues> AttendeeList = this.getAttandees();
michael@0 1015 for (ContentValues Attendee : AttendeeList) {
michael@0 1016 this.mProvider.insert(Attendees.CONTENT_URI, Attendee);
michael@0 1017 }
michael@0 1018 Log.d(TAG, "Attendees Inserted:" + String.valueOf(AttendeeList.size()));
michael@0 1019 Result = true;
michael@0 1020 } catch (RemoteException e) {
michael@0 1021 e.printStackTrace();
michael@0 1022 }
michael@0 1023
michael@0 1024 return Result;
michael@0 1025 }
michael@0 1026
michael@0 1027 /**
michael@0 1028 * update the reminders from a calendarEvent to its androidEvent.
michael@0 1029 * the calendarEvent has to know its androidEvent via {@link CalendarEvent#setAndroidEventUri(Uri)}
michael@0 1030 * @param provider
michael@0 1031 * @return
michael@0 1032 * @see SyncAdapter#updateAndroidEvent(ContentProviderClient, Account, AndroidEvent, CalendarEvent)
michael@0 1033 */
michael@0 1034 private boolean updateAndroidReminder() {
michael@0 1035 boolean Result = false;
michael@0 1036
michael@0 1037 try {
michael@0 1038 String mSelectionClause = "(" + Reminders.EVENT_ID + " = ?)";
michael@0 1039 String[] mSelectionArgs = {Long.toString(ContentUris.parseId(this.getAndroidEventUri())) };
michael@0 1040 int RowDelete;
michael@0 1041 RowDelete = this.mProvider.delete(Reminders.CONTENT_URI, mSelectionClause, mSelectionArgs);
michael@0 1042 Log.d(TAG, "Reminders Deleted:" + String.valueOf(RowDelete));
michael@0 1043
michael@0 1044
michael@0 1045 Uri ReminderUri;
michael@0 1046 java.util.ArrayList<ContentValues> ReminderList = this.getReminders();
michael@0 1047 for (ContentValues Reminder : ReminderList) {
michael@0 1048 ReminderUri = this.mProvider.insert(Reminders.CONTENT_URI, Reminder);
michael@0 1049 System.out.println(ReminderUri);
michael@0 1050 }
michael@0 1051 Log.d(TAG, "Reminders Inserted:" + String.valueOf(ReminderList.size()));
michael@0 1052
michael@0 1053 Result = true;
michael@0 1054 } catch (RemoteException e) {
michael@0 1055 e.printStackTrace();
michael@0 1056 }
michael@0 1057
michael@0 1058 return Result;
michael@0 1059 }
michael@0 1060
michael@0 1061 private static Uri asSyncAdapter(Uri uri, String account, String accountType) {
michael@0 1062 return uri.buildUpon()
michael@0 1063 .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
michael@0 1064 .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
michael@0 1065 .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
michael@0 1066 }
michael@0 1067 }
michael@0 1068

mercurial