4 * Created on 26 November 2006, 15:44
5 * Copyright (C) Mathew McBride 2006-2007
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 package net
.bionicmessage
.funambol
.datakit
;
22 import java
.text
.ParseException
;
23 import java
.util
.logging
.Level
;
24 import java
.util
.logging
.Logger
;
25 import net
.bionicmessage
.utils
.QPDecode
;
26 import com
.funambol
.common
.pim
.calendar
.RecurrencePattern
;
27 import com
.funambol
.common
.pim
.calendar
.RecurrencePatternException
;
28 import com
.funambol
.common
.pim
.calendar
.Task
;
29 import com
.funambol
.common
.pim
.converter
.CalendarStatus
;
30 import com
.funambol
.common
.pim
.converter
.VCalendarConverter
;
31 import com
.funambol
.common
.pim
.model
.VCalendar
;
32 import java
.io
.FileInputStream
;
33 import net
.fortuna
.ical4j
.model
.*;
34 import net
.fortuna
.ical4j
.model
.Property
.*;
36 import net
.fortuna
.ical4j
.data
.*;
37 import java
.util
.ArrayList
;
38 import java
.util
.Iterator
;
39 import java
.util
.List
;
40 import net
.bionicmessage
.funambol
.framework
.Constants
;
41 import net
.bionicmessage
.utils
.QPDecode
;
42 import net
.fortuna
.ical4j
.model
.component
.VAlarm
;
43 import net
.fortuna
.ical4j
.model
.component
.VEvent
;
44 import net
.fortuna
.ical4j
.model
.component
.VToDo
;
45 import net
.fortuna
.ical4j
.model
.parameter
.AltRep
;
46 import net
.fortuna
.ical4j
.model
.parameter
.Encoding
;
47 import net
.fortuna
.ical4j
.model
.parameter
.PartStat
;
48 import net
.fortuna
.ical4j
.model
.parameter
.Related
;
49 import net
.fortuna
.ical4j
.model
.property
.Attendee
;
50 import net
.fortuna
.ical4j
.model
.property
.Categories
;
51 import net
.fortuna
.ical4j
.model
.property
.DateProperty
;
52 import net
.fortuna
.ical4j
.model
.property
.Description
;
53 import net
.fortuna
.ical4j
.model
.property
.DtEnd
;
54 import net
.fortuna
.ical4j
.model
.property
.DtStart
;
55 import net
.fortuna
.ical4j
.model
.property
.Due
;
56 import net
.fortuna
.ical4j
.model
.property
.ExDate
;
57 import net
.fortuna
.ical4j
.model
.property
.Location
;
58 import net
.fortuna
.ical4j
.model
.property
.Priority
;
59 import net
.fortuna
.ical4j
.model
.property
.RRule
;
60 import net
.fortuna
.ical4j
.model
.property
.Status
;
61 import net
.fortuna
.ical4j
.model
.property
.Summary
;
62 import net
.fortuna
.ical4j
.model
.property
.Transp
;
63 import net
.fortuna
.ical4j
.model
.property
.Trigger
;
64 import net
.fortuna
.ical4j
.model
.property
.Uid
;
67 * Provides utilities for converting ical4j data objects to Fumambol
71 public class ical4j2funambol
{
73 /** Creates a new instance of ical4j2funambol */
74 public static com
.funambol
.common
.pim
.calendar
.Calendar
convertIcal4jToFunambolEvent(net
.fortuna
.ical4j
.model
.Calendar ical4j_in
, String clientType
) throws RecurrencePatternException
{
77 /* QP decode a second time just to be sure. (the first is in object store/jgroupdav) */
78 net
.fortuna
.ical4j
.model
.Calendar ical4j
= QPDecode
.decodeQP(ical4j_in
);
79 /* Setup a funambol event */
80 com
.funambol
.common
.pim
.calendar
.Calendar fnblcal
= new com
.funambol
.common
.pim
.calendar
.Calendar();
81 com
.funambol
.common
.pim
.calendar
.CalendarContent fnblcontent
= null;
82 Component comp
= null;
83 comp
= (Component
) ical4j
.getComponents().getComponent(Component
.VEVENT
);
85 comp
= (Component
) ical4j
.getComponents().getComponent(Component
.VTODO
);
86 fnblcontent
= new com
.funambol
.common
.pim
.calendar
.Task();
87 fnblcal
.setTask((Task
) fnblcontent
);
89 fnblcontent
= new com
.funambol
.common
.pim
.calendar
.Event();
90 fnblcal
.setEvent((com
.funambol
.common
.pim
.calendar
.Event
) fnblcontent
);
93 String startDate
= ""; /* If we get DtStart, then cache it for Funambol recur */
94 DtStart dts
= null; /* Also cache dtstart */
95 /* Blatantly obvious attributes */
96 if (comp
.getProperty(Uid
.UID
) != null) {
97 Uid uid
= (Uid
) comp
.getProperty(Uid
.UID
);
98 com
.funambol
.common
.pim
.common
.Property uidprop
=
99 new com
.funambol
.common
.pim
.common
.Property(uid
.getValue());
100 fnblcontent
.setUid(uidprop
);
102 /* if (comp.getProperty(LastModified.LAST_MODIFIED) != null) {
103 LastModified lm = (LastModified)comp.getProperty(LastModified.LAST_MODIFIED);
104 com.funambol.common.pim.common.Property lmprop =
105 new com.funambol.common.pim.common.Property();
107 lmprop.setPropertyValue(lm.getValue());
108 fnblcontent.setLastModified(lmprop);
110 /* if (comp.getProperty(Clazz.CLASS) != null) {
111 Clazz cl = (Clazz)comp.getProperty(Clazz.CLASS);
112 com.funambol.common.pim.common.Property clprop =
113 new com.funambol.common.pim.common.Property(cl.getValue());
116 /* Start off with basic attributes.. DTSTART, DTEND, SUMMARY, DESCRIPTION, LOCATION,
118 // Do not convert DTSTART for VToDo (rejected by some clients)
119 if (comp
.getProperty(DtStart
.DTSTART
) != null &&
120 !comp
.getName().equals(VToDo
.VTODO
)) {
121 dts
= (DtStart
) comp
.getProperty(DtStart
.DTSTART
);
122 Parameter v
= dts
.getParameter("VALUE");
124 v
.getValue().equals("DATE")) {
125 String newValue
= dts
.getValue();
126 attachAllDayDtStart(fnblcontent
, newValue
, clientType
);
129 com
.funambol
.common
.pim
.common
.Property dtsprop
= new com
.funambol
.common
.pim
.common
.Property(dts
.getValue());
130 fnblcontent
.setDtStart(dtsprop
);
131 dstime
= dts
.getDate().getTime();
132 fnblcontent
.setAllDay(false);
134 startDate
= fnblcontent
.getDtStart().getPropertyValueAsString();
136 if (comp
.getProperty(DtEnd
.DTEND
) != null) {
137 DtEnd dte
= (DtEnd
) comp
.getProperty(DtEnd
.DTEND
);
138 Parameter v
= dte
.getParameter("VALUE");
140 v
.getValue().equals("DATE")) {
141 String newValue
= dte
.getValue();
142 attachAllDayDtEnd(fnblcontent
, newValue
, clientType
);
145 com
.funambol
.common
.pim
.common
.Property dteprop
=
146 new com
.funambol
.common
.pim
.common
.Property(dte
.getValue());
147 fnblcontent
.setDtEnd(dteprop
);
148 detime
= dte
.getDate().getTime();
149 fnblcontent
.setAllDay(false);
152 if (comp
.getProperty(Due
.DUE
) != null && comp
.getProperty(DtEnd
.DTEND
) == null) {
153 Due due
= (Due
) comp
.getProperty(Due
.DUE
);
154 Parameter v
= due
.getParameter("VALUE");
156 v
.getValue().equals("DATE")) {
157 String newValue
= due
.getValue();
158 attachAllDayDtEnd(fnblcontent
, newValue
, clientType
);
161 com
.funambol
.common
.pim
.common
.Property dteprop
=
162 new com
.funambol
.common
.pim
.common
.Property(due
.getValue());
163 fnblcontent
.setDtEnd(dteprop
);
166 /** See if an all day event hasn't sneaked in via the back door */
167 if (detime
- dstime
== 86340000 || detime
- dstime
== 86399000) {
168 /* See the vObject minimum interoperability profile - OMA
169 * (OMA-TS-vObjectOMAProfile-V1_0-20050118-C) for information on how to
170 * correctly establish an all day event */
171 fnblcontent
.setAllDay(true);
172 DtEnd dte
= (DtEnd
) comp
.getProperty(DtEnd
.DTEND
);
174 net
.fortuna
.ical4j
.model
.Date dt
= new net
.fortuna
.ical4j
.model
.Date(dte
.getDate().getTime());
176 net
.fortuna
.ical4j
.model
.Date ds
= new net
.fortuna
.ical4j
.model
.Date(dts
.getDate().getTime());
178 attachAllDayDtStart(fnblcontent
, dts
.getValue(), clientType
);
179 attachAllDayDtEnd(fnblcontent
, dte
.getValue(), clientType
);
181 if (comp
.getProperty(Summary
.SUMMARY
) != null) {
182 /* We need to consider text encodings for this.
183 * ical2 specifies 8 bit and base64 in spec, but vcal1
184 * also allows quoted-printable (EVIL!!!). */
185 Summary summ
= (Summary
) comp
.getProperty(Summary
.SUMMARY
);
186 com
.funambol
.common
.pim
.common
.Property summprop
=
187 new com
.funambol
.common
.pim
.common
.Property();
188 // Check for encodings
189 if (summ
.getParameter(Encoding
.ENCODING
) != null) {
190 Encoding enc
= (Encoding
) summ
.getParameter(Encoding
.ENCODING
);
191 summprop
.setEncoding(enc
.getValue());
193 summprop
.setPropertyValue(summ
.getValue());
194 fnblcontent
.setSummary(summprop
);
196 if (comp
.getProperty(Description
.DESCRIPTION
) != null) {
197 /* We also need to consider alternative text encoding here */
198 Description des
= (Description
) comp
.getProperty(Description
.DESCRIPTION
);
199 com
.funambol
.common
.pim
.common
.Property desprop
=
200 new com
.funambol
.common
.pim
.common
.Property();
201 // Check for encdoings
202 if (des
.getParameter(Encoding
.ENCODING
) != null) {
203 Encoding enc
= (Encoding
) des
.getParameter(Encoding
.ENCODING
);
204 desprop
.setEncoding(enc
.getValue());
206 desprop
.setPropertyValue(des
.getValue());
207 fnblcontent
.setDescription(desprop
);
209 if (comp
.getProperty(Location
.LOCATION
) != null) {
210 Location loc
= (Location
) comp
.getProperty(Location
.LOCATION
);
211 com
.funambol
.common
.pim
.common
.Property locprop
=
212 new com
.funambol
.common
.pim
.common
.Property();
213 // Is our location pointing to a URL?
214 if (loc
.getParameter(AltRep
.ALTREP
) != null) {
215 AltRep url
= (AltRep
) loc
.getParameter(AltRep
.ALTREP
);
216 locprop
.setValue("URL");
217 locprop
.setType("VCARD");
219 locprop
.setPropertyValue(loc
.getValue());
220 fnblcontent
.setLocation(locprop
);
222 if (comp
.getProperty(Priority
.PRIORITY
) != null) {
223 Priority pri
= (Priority
) comp
.getProperty(Priority
.PRIORITY
);
224 com
.funambol
.common
.pim
.common
.Property priprop
=
225 new com
.funambol
.common
.pim
.common
.Property(pri
.getValue());
226 fnblcontent
.setPriority(priprop
);
227 } else if (comp
.getName().equals(VToDo
.VTODO
)) {
228 com
.funambol
.common
.pim
.common
.Property priprop
=
229 new com
.funambol
.common
.pim
.common
.Property("1");
230 fnblcontent
.setPriority(priprop
);
232 /* Slightly harder */
233 if (comp
.getProperty(Transp
.TRANSP
) != null && fnblcontent
instanceof com
.funambol
.common
.pim
.calendar
.Event
) {
234 Transp tsp
= (Transp
) comp
.getProperty(Transp
.TRANSP
);
235 com
.funambol
.common
.pim
.common
.Property tspprop
=
236 new com
.funambol
.common
.pim
.common
.Property();
237 if (tsp
.getValue().equals(Transp
.OPAQUE
)) {
238 // This event WILL show up as busy
239 tspprop
.setPropertyValue("0");
240 } else { // What calendar app couldn't chose between OPAQUE and TRANSPARENT?
241 tspprop
.setPropertyValue("1");
243 com
.funambol
.common
.pim
.calendar
.Event e
=
244 (com
.funambol
.common
.pim
.calendar
.Event
) fnblcontent
;
245 e
.setTransp(tspprop
);
247 if (comp
.getProperty(Status
.STATUS
) != null &&
248 fnblcontent
instanceof com
.funambol
.common
.pim
.calendar
.Task
) {
249 Status status
= (Status
) comp
.getProperty(Status
.STATUS
);
250 com
.funambol
.common
.pim
.common
.Property stat
=
251 new com
.funambol
.common
.pim
.common
.Property();
252 CalendarStatus cstatus
= CalendarStatus
.mapVcalIcalStatus(status
.getValue());
253 if (fnblcontent
instanceof com
.funambol
.common
.pim
.calendar
.Event
) {
254 stat
.setPropertyValue(cstatus
.getVCalICalValue(true));
255 } else if (fnblcontent
instanceof com
.funambol
.common
.pim
.calendar
.Task
) {
256 stat
.setPropertyValue(cstatus
.getServerValue());
258 fnblcontent
.setStatus(stat
);
260 PropertyList attendees
= comp
.getProperties("ATTENDEE");
261 List
<com
.funambol
.common
.pim
.calendar
.Attendee
> fnblattendees
=
262 fnblcontent
.getAttendees();
263 Iterator attendeeIterator
= attendees
.iterator();
264 while (attendeeIterator
.hasNext()) {
265 Attendee att
= (Attendee
) attendeeIterator
.next();
266 com
.funambol
.common
.pim
.calendar
.Attendee fnblatt
= AttendeeConverter
.icalToFunambol(att
);
267 if (fnblatt
!= null) {
268 fnblattendees
.add(fnblatt
);
271 if (comp
.getProperty(Categories
.CATEGORIES
) != null) {
272 Categories cat
= (Categories
) comp
.getProperty(Categories
.CATEGORIES
);
273 fnblcontent
.getCategories().setPropertyValue(cat
.getValue());
275 if (comp
.getProperty(RRule
.RRULE
) != null) {
276 RRule rr
= (RRule
) comp
.getProperty(RRule
.RRULE
);
277 Recur r
= rr
.getRecur();
278 ArrayList
<com
.funambol
.common
.pim
.calendar
.ExceptionToRecurrenceRule
>
279 exceptionList
= new ArrayList(2);
280 if (comp
.getProperty(ExDate
.EXDATE
) != null) {
281 ExDate ex
= (ExDate
)comp
.getProperty("EXDATE");
282 String value
= ex
.getValue();
283 String
[] params
= value
.split(",");
284 for (int i
= 0; i
< params
.length
; i
++) {
286 String val
= params
[i
];
287 com
.funambol
.common
.pim
.calendar
.ExceptionToRecurrenceRule etrr
= new com
.funambol
.common
.pim
.calendar
.ExceptionToRecurrenceRule(false, val
);
288 exceptionList
.add(etrr
);
289 } catch (ParseException ex1
) {
290 ex1
.printStackTrace();
294 /* This is where things start getting insane. Funambol wants us to
295 * find out every property of the recurrance rule and then use a custom
296 * constructor for each case! */
297 /* ical2 RULE VIOLATION: VEVENT may contain multiple RRULES... */
298 String freq
= r
.getFrequency();
300 int interval
= (r
.getInterval() > 0) ? r
.getInterval() : 1;
301 int count
= r
.getCount();
302 boolean noEndDate
= false;
304 if (r
.getUntil() == null) {
307 net
.fortuna
.ical4j
.model
.Date eDate
=
308 new net
.fortuna
.ical4j
.model
.Date(r
.getUntil());
309 endDate
= eDate
.toString();
311 short dayOfWeekMask
= 0;
312 if (freq
.equals(Recur
.DAILY
)) {
314 RecurrencePattern rp
= RecurrencePattern
.getDailyRecurrencePattern(interval
,
320 fnblcontent
.setRecurrencePattern(rp
);
322 } catch (RecurrencePatternException re
) {
323 re
.printStackTrace();
324 // Send all RecurrencePatternExceptions to ground for now
326 } else if (freq
.equals(Recur
.HOURLY
)) {
327 /* NOT SUPPORTED BY VCAL1 AND FUNAMBOL */
328 } else if (freq
.equals(Recur
.WEEKLY
)) {
331 ArrayList wkdaylist
= r
.getDayList();
332 for (int i
= 0; i
< wkdaylist
.size(); i
++) {
333 WeekDay wday
= (WeekDay
) wkdaylist
.get(i
);
334 String day
= wday
.getDay();
335 if (day
.equals("SU")) {
337 } else if (day
.equals("MO")) {
338 dayOfWeekMask
= (short) (dayOfWeekMask
+ 2);
339 } else if (day
.equals("TU")) {
340 dayOfWeekMask
= (short) (dayOfWeekMask
+ 4);
341 } else if (day
.equals("WE")) {
342 dayOfWeekMask
= (short) (dayOfWeekMask
+ 8);
343 } else if (day
.equals("TU")) {
344 dayOfWeekMask
= (short) (dayOfWeekMask
+ 16);
345 } else if (day
.equals("FR")) {
346 dayOfWeekMask
= (short) (dayOfWeekMask
+ 32);
347 } else if (day
.equals("SA")) {
348 dayOfWeekMask
= (short) (dayOfWeekMask
+ 64);
351 RecurrencePattern rp
= RecurrencePattern
.getWeeklyRecurrencePattern(interval
,
357 fnblcontent
.setRecurrencePattern(rp
);
358 } catch (RecurrencePatternException re
) {
359 re
.printStackTrace();
361 } else if (freq
.equals(Recur
.MONTHLY
)) {
362 /* Monthly - we have two sorts of month recurrance - by number day of month
363 * or day of week of month */
364 // Do we have a set week position
365 if (r
.getDayList().size() > 0) {
366 // Get the weekday instance
367 WeekDay wd
= (WeekDay
) r
.getDayList().get(0);
368 String day
= wd
.getDay();
369 int week
= wd
.getOffset();
370 Integer weekoffset
= new Integer(week
);
371 if (day
.equals("SU")) {
373 } else if (day
.equals("MO")) {
374 dayOfWeekMask
= (short) (dayOfWeekMask
+ 2);
375 } else if (day
.equals("TU")) {
376 dayOfWeekMask
= (short) (dayOfWeekMask
+ 4);
377 } else if (day
.equals("WE")) {
378 dayOfWeekMask
= (short) (dayOfWeekMask
+ 8);
379 } else if (day
.equals("TU")) {
380 dayOfWeekMask
= (short) (dayOfWeekMask
+ 16);
381 } else if (day
.equals("FR")) {
382 dayOfWeekMask
= (short) (dayOfWeekMask
+ 32);
383 } else if (day
.equals("SA")) {
384 dayOfWeekMask
= (short) (dayOfWeekMask
+ 64);
386 RecurrencePattern rp
= RecurrencePattern
.getMonthNthRecurrencePattern(
389 weekoffset
.shortValue(),
394 fnblcontent
.setRecurrencePattern(rp
);
397 java
.util
.Calendar mcal
= java
.util
.Calendar
.getInstance();
398 mcal
.setTime(dts
.getDate());
399 Integer dayOfMonth
= new Integer(mcal
.get(java
.util
.Calendar
.DAY_OF_MONTH
));
400 dayOfWeekMask
= dayOfMonth
.shortValue();
401 RecurrencePattern rp
= RecurrencePattern
.getMonthlyRecurrencePattern(interval
,
407 fnblcontent
.setRecurrencePattern(rp
);
408 } catch (RecurrencePatternException re
) {
409 re
.printStackTrace();
413 } else if (freq
.equals(Recur
.YEARLY
)) {
414 // Same as monthly recurrence basically.
415 if (r
.getDayList().size() > 0) {
416 WeekDay wd
= (WeekDay
) r
.getDayList().get(0);
417 String day
= wd
.getDay();
418 int week
= wd
.getOffset();
419 Integer weekoffset
= new Integer(week
);
420 Integer month
= (Integer
) r
.getMonthList().get(0);
421 if (day
.equals("SU")) {
423 } else if (day
.equals("MO")) {
424 dayOfWeekMask
= (short) (dayOfWeekMask
+ 2);
425 } else if (day
.equals("TU")) {
426 dayOfWeekMask
= (short) (dayOfWeekMask
+ 4);
427 } else if (day
.equals("WE")) {
428 dayOfWeekMask
= (short) (dayOfWeekMask
+ 8);
429 } else if (day
.equals("TU")) {
430 dayOfWeekMask
= (short) (dayOfWeekMask
+ 16);
431 } else if (day
.equals("FR")) {
432 dayOfWeekMask
= (short) (dayOfWeekMask
+ 32);
433 } else if (day
.equals("SA")) {
434 dayOfWeekMask
= (short) (dayOfWeekMask
+ 64);
436 RecurrencePattern rp
= RecurrencePattern
.getYearNthRecurrencePattern(r
.getInterval(),
439 weekoffset
.shortValue(),
445 if (r
.getInterval() < 0) {
449 RecurrencePattern rp
= RecurrencePattern
.getYearlyRecurrencePattern(
457 fnblcontent
.setRecurrencePattern(rp
);
458 } catch (Exception ex
) {
459 ex
.printStackTrace();
463 if (fnblcontent
.getRecurrencePattern() != null) {
465 fnblcontent
.getRecurrencePattern().setExceptions(exceptionList
);
466 } catch (Exception e
) {
471 com
.funambol
.common
.pim
.common
.Property prodid
=
472 new com
.funambol
.common
.pim
.common
.Property("-//BionicMessage Funambol Connector//ical4jFunambolconvert//EN");
473 fnblcal
.setProdId(prodid
);
474 com
.funambol
.common
.pim
.common
.Property ver
=
475 new com
.funambol
.common
.pim
.common
.Property("1.0");
476 fnblcal
.setVersion(ver
);
478 /* NOT YET CONVERTED: attach / attendee / exdate / exrule / geo / seq
482 public static void attachAllDayDtEnd(com
.funambol
.common
.pim
.calendar
.CalendarContent e
, String newValue
, String clientType
) {
483 if (clientType
.equals("text/x-vcalendar")) {
484 newValue
= newValue
+ "T240000";
485 com
.funambol
.common
.pim
.common
.Property dteprop
=
486 new com
.funambol
.common
.pim
.common
.Property(newValue
);
488 e
.getDtEnd().setPropertyValue(newValue
);
489 } else if (clientType
.equals("text/x-s4j-sife")) {
490 e
.getDtEnd().setPropertyValue(newValue
);
495 public static void attachAllDayDtStart(com
.funambol
.common
.pim
.calendar
.CalendarContent e
, String newValue
, String clientType
) {
496 if (clientType
.equals("text/x-vcalendar")) {
497 newValue
= newValue
+ "T000000";
498 com
.funambol
.common
.pim
.common
.Property dtsprop
=
499 new com
.funambol
.common
.pim
.common
.Property(newValue
);
501 e
.getDtStart().setPropertyValue(newValue
);
502 } else if (clientType
.equals("text/x-s4j-sife")) {
503 e
.getDtStart().setPropertyValue(newValue
);
508 /** Process any alarms in the event/todo. Since this functionality is optional,
509 * it is in another function
511 public static void attachAlarm(com
.funambol
.common
.pim
.calendar
.CalendarContent e
,
512 net
.fortuna
.ical4j
.model
.component
.CalendarComponent ical4je
) {
513 ComponentList alarms
= null;
514 if (ical4je
instanceof VEvent
) {
515 VEvent ve
= (VEvent
) ical4je
;
516 alarms
= ve
.getAlarms();
517 } else if (ical4je
instanceof VToDo
) {
518 VToDo vt
= (VToDo
) ical4je
;
519 alarms
= vt
.getAlarms();
523 Iterator alarmIterator
= alarms
.iterator();
524 while (alarmIterator
.hasNext()) {
525 VAlarm va
= (VAlarm
) alarmIterator
.next();
527 Trigger t
= va
.getTrigger();
528 String
[] dalarmComponents
= {"", "", "", ""};
529 if (va
.getAction().getValue().equals("DISPLAY")) {
530 if (t
.getDateTime() != null) {
531 dalarmComponents
[0] = t
.getDateTime().toString();
532 } else if (t
.getDuration() != null) {
533 Dur dur
= t
.getDuration();
534 DateProperty relatedTo
= null;
535 if (t
.getParameter(Related
.RELATED
) != null &&
536 t
.getParameter(Related
.RELATED
).equals(Related
.END
)) {
537 relatedTo
= (DateProperty
) ical4je
.getProperty(DtEnd
.DTEND
);
539 relatedTo
= (DateProperty
) ical4je
.getProperty(DtStart
.DTSTART
);
541 Date dt
= relatedTo
.getDate();
542 // Calculate a new DateTime relative to dt
543 java
.util
.Calendar cal
= java
.util
.Calendar
.getInstance();
545 cal
.add(java
.util
.Calendar
.SECOND
, -(dur
.getSeconds()));
546 cal
.add(java
.util
.Calendar
.MINUTE
, -(dur
.getMinutes()));
547 cal
.add(java
.util
.Calendar
.HOUR
, -(dur
.getHours()));
548 cal
.add(java
.util
.Calendar
.DAY_OF_YEAR
, -(dur
.getDays()));
549 cal
.add(java
.util
.Calendar
.WEEK_OF_YEAR
, -(dur
.getWeeks()));
550 DateTime newDate
= new DateTime(cal
.getTime());
551 newDate
.setUtc(true);
552 dalarmComponents
[0] = newDate
.toString();
555 StringBuffer buf
= new StringBuffer();
556 for (int i
= 0; i
< dalarmComponents
.length
; i
++) {
557 if (dalarmComponents
[i
] != null) {
558 buf
.append(dalarmComponents
[i
]);
560 if (dalarmComponents
.length
!= i
- 1) {
564 e
.setDAlarm(new com
.funambol
.common
.pim
.common
.Property(buf
.toString()));
567 public static com
.funambol
.common
.pim
.calendar
.Attendee
568 attachPartStat(PartStat ps
,
569 com
.funambol
.common
.pim
.calendar
.Attendee att
) {
570 com
.funambol
.common
.pim
.calendar
.Attendee fnblatt
= att
;
571 if (PartStat
.ACCEPTED
.equals(ps
)) {
572 fnblatt
.setStatus(com
.funambol
.common
.pim
.calendar
.Attendee
.ACCEPTED
);
573 } else if (PartStat
.DECLINED
.equals(ps
)) {
574 fnblatt
.setStatus(com
.funambol
.common
.pim
.calendar
.Attendee
.DECLINED
);
575 } else if (PartStat
.DELEGATED
.equals(ps
)) {
576 fnblatt
.setStatus(com
.funambol
.common
.pim
.calendar
.Attendee
.DELEGATED
);
577 } else if (PartStat
.TENTATIVE
.equals(ps
)) {
578 fnblatt
.setStatus(com
.funambol
.common
.pim
.calendar
.Attendee
.TENTATIVE
);
582 /** Standalone tester */
583 public static void main(String args
[]) {
584 if (args
.length
< 1) {
585 System
.err
.println("Arguments: ical4j2funambol <file.ics>");
589 String file
= args
[0];
590 FileInputStream fis
= new FileInputStream(file
);
591 CalendarBuilder cbuild
= new CalendarBuilder();
592 Calendar ics
= cbuild
.build(fis
);
593 com
.funambol
.common
.pim
.calendar
.Calendar fnblcal
=
594 ical4j2funambol
.convertIcal4jToFunambolEvent(ics
, "text/x-vcalendar");
595 VCalendarConverter vcc
= new VCalendarConverter(null, "UTF-8",false);
596 VCalendar vc
= vcc
.calendar2vcalendar(fnblcal
, true);
597 System
.out
.println(vc
.toString());
598 } catch (Exception e
) {