From 41f4186ca3299d271233ad7bfd4baecc8b59f067 Mon Sep 17 00:00:00 2001 From: Mathew McBride Date: Sun, 24 Feb 2008 12:22:06 +1100 Subject: [PATCH] Alarm conversion support option added. Only tested with Synthesis and KOrganizer for now. Use with caution --- .gitignore | 1 + build.properties | 6 +- doc/problem-samples/ical-alarm.ics | 82 +++++++++++++++++++++ doc/testData/korganizer-15min-alarm.ics | 25 +++++++ lib/JGroupDAV.jar | Bin 113984 -> 115685 bytes nbproject/project.properties | 6 +- src/net/bionicmessage/funambol/BVersion.java | 2 +- .../admin/MultipleCalendarSourceAdminPanel.form | 20 +++-- .../admin/MultipleCalendarSourceAdminPanel.java | 20 ++++- .../funambol/datakit/funambol2ical4j.java | 74 +++++++++++++++---- .../funambol/datakit/ical4j2funambol.java | 67 +++++++++++++++++ .../funambol/framework/Constants.java | 2 + .../funambol/framework/SourceObject.java | 3 + .../groupdav/calendar/CalendarSyncSource.java | 1 + .../calendar/InboundFunambolCalendarObject.java | 15 ++-- .../calendar/OutboundFunambolCalendarObject.java | 16 +++- .../groupdav/calendar/iCalSourceObject.java | 11 +++ .../contacts/InboundFunambolContactObject.java | 9 ++- .../funambol/datakit/ical4j2funambolTest.java | 32 ++++++-- .../groupdav/contacts/ContactSyncSourceTest.java | 2 +- 20 files changed, 343 insertions(+), 51 deletions(-) create mode 100644 doc/problem-samples/ical-alarm.ics create mode 100644 doc/testData/korganizer-15min-alarm.ics diff --git a/.gitignore b/.gitignore index 7b1e298..3dfc133 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ output/* *.s4j build/* +.DS_Store diff --git a/build.properties b/build.properties index 3a06397..b0ce6d1 100644 --- a/build.properties +++ b/build.properties @@ -1,6 +1,6 @@ #build props -#Mon Feb 04 19:45:59 EST 2008 +#Sun Feb 24 12:20:15 EST 2008 groupdav.release.major=2 groupdav.release.minor=0 -groupdav.build.date=2008/02/04 19\:45 -groupdav.build.number=0115 +groupdav.build.date=2008/02/24 12\:20 +groupdav.build.number=0215 diff --git a/doc/problem-samples/ical-alarm.ics b/doc/problem-samples/ical-alarm.ics new file mode 100644 index 0000000..cfb38f0 --- /dev/null +++ b/doc/problem-samples/ical-alarm.ics @@ -0,0 +1,82 @@ +BEGIN:VCALENDAR +METHOD:PUBLISH +X-WR-TIMEZONE:Australia/Canberra +PRODID:-//Apple Inc.//iCal 3.0//EN +CALSCALE:GREGORIAN +X-WR-CALNAME:Home +VERSION:2.0 +X-WR-RELCALID:491C7295-FB88-429E-A182-2412E0DD2F67 +X-APPLE-CALENDAR-COLOR:#0252D4 +BEGIN:VTIMEZONE +TZID:Australia/Canberra +BEGIN:DAYLIGHT +TZOFFSETFROM:+1000 +TZOFFSETTO:+1100 +DTSTART:20011028T020000 +RRULE:FREQ=YEARLY;UNTIL=20071027T160000Z;BYMONTH=10;BYDAY=-1SU +TZNAME:EST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+1100 +TZOFFSETTO:+1000 +DTSTART:20060402T030000 +RDATE:20060402T030000 +RDATE:20070325T030000 +TZNAME:EST +END:STANDARD +BEGIN:STANDARD +TZOFFSETFROM:+1100 +TZOFFSETTO:+1000 +DTSTART:20080406T030000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU +TZNAME:EST +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +SEQUENCE:0 +TRANSP:OPAQUE +UID:831DB3FD-C970-4129-88D5-6D82AC11C724 +DTSTART;TZID=Australia/Canberra:20071026T100000 +DTSTAMP:20071113T095806Z +SUMMARY:Year 12 Grad ceremony +CREATED:20080212T081430Z +DTEND;TZID=Australia/Canberra:20071026T130000 +LOCATION:Costa Hall +END:VEVENT +BEGIN:VEVENT +SEQUENCE:0 +TRANSP:OPAQUE +UID:751D0F72-9F3A-4500-A8C4-B00AAEBBE753 +DTSTART;VALUE=DATE:20071027 +DTSTAMP:20071113T095806Z +SUMMARY:All day memo +CREATED:20080212T081430Z +DTEND;VALUE=DATE:20071028 +END:VEVENT +BEGIN:VEVENT +SEQUENCE:2 +TRANSP:TRANSPARENT +UID:A21A8CD8-0736-4B3C-9EDC-515A9EC700D0 +DTSTART;VALUE=DATE:20071218 +DTSTAMP:20071218T101801Z +SUMMARY:all day events +CREATED:20080212T081430Z +DTEND;VALUE=DATE:20071219 +END:VEVENT +BEGIN:VEVENT +SEQUENCE:2 +TRANSP:OPAQUE +UID:D372BBFA-C60B-4EB5-8331-D7A44574FE9B +DTSTART;TZID=Australia/Canberra:20080222T043000 +DTSTAMP:20080222T103043Z +SUMMARY:gimme alarms +CREATED:20080222T103028Z +DTEND;TZID=Australia/Canberra:20080222T053000 +BEGIN:VALARM +X-WR-ALARMUID:B688AEEE-8190-4145-8988-0EDFA576E2B8 +ACTION:AUDIO +TRIGGER:-PT15M +ATTACH;VALUE=URI:Basso +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/doc/testData/korganizer-15min-alarm.ics b/doc/testData/korganizer-15min-alarm.ics new file mode 100644 index 0000000..c31764b --- /dev/null +++ b/doc/testData/korganizer-15min-alarm.ics @@ -0,0 +1,25 @@ +BEGIN:VCALENDAR +PRODID:-//K Desktop Environment//NONSGML KOrganizer 3.5.6//EN +VERSION:2.0 +BEGIN:VEVENT +DTSTAMP:20080223T071825Z +ORGANIZER;CN=Mathew McBride +CREATED:20080223T071814Z +UID:KOrganizer-1058019350.309 +SEQUENCE:0 +LAST-MODIFIED:20080223T071814Z +SUMMARY:test event with reminder +LOCATION: +CLASS:PUBLIC +PRIORITY:5 +DTSTART:20080222T024500Z +DTEND:20080222T044500Z +TRANSP:OPAQUE +BEGIN:VALARM +DESCRIPTION: +ACTION:DISPLAY +TRIGGER;VALUE=DURATION:-PT15M +END:VALARM + +END:VEVENT +END:VCALENDAR \ No newline at end of file diff --git a/lib/JGroupDAV.jar b/lib/JGroupDAV.jar index df4fe947531c385a31a7798dffb8baa73843ffbd..8d1a2cb6ba276d84e897421c67a32fb89821ebb1 100644 GIT binary patch delta 1530 zcwTLkUrbw79LK*u+TL4kFN}W`N~eGbE9E}}?8<;SMkDekgfX0is14lV)za3sE^#p- zOP077HOo!x5`CGPZN|im7+PRt@~}PlXY=2S@o8CNeDJ|NtJ(aWLyL^;Bfb@^M1< z9`#7uEjlRVSO3sGr-ZxOYN3RS71Lc3{tC^yB#ccRQY4%|IbJH^S2H>wVdQGn^AZ;B z`wk1pe$Yanh9vbQDISn?^$WVE?cbF~;PczI7f1m_Z(&`!_8L{4Fz3UOaU-#4oJg6G zWZQfsoJ@ZEVB-cmbYfUT5e_)v)6fLJie?RVv}kBWn;6eRy=Aeph6+PC? z$`JXi3wpUVu%dK6xbl$IN7kEyM;IA=u4mDz+WjxbIXVwnT6UVGx={-12;E zDISX&(Nz1)@M#ttTPz&@Pl_YNA{a3MjPj&t)bsWKS z!tJPzAsiz#%5yA!GzIJIO*hFvYjD+BM$i|H)KGpiLcprK<+dJXtF5I~S6LAocYj=y zj|=ZD*;CjCv7BeOl8c-)&u{^3zNV4%o5fV?RC%e1@RDKOKklKv+%BHVJxkfb3k#gN zPoBfhsW#1`4m#gB(F#DKf;^V+teqvXbojHN6=^QzQIX09l<}x|MxmuDPrr1KSqt<1HCDCj4@`%=4h#V`oj!Ve3`gN^1tnC+KK(D;cO;a0XS6-J@nu zn1L2_dYo+j7%q=P=v*(JQ|QXW+x}}iNwvWxGuF_-`FElkUHo0${CD&qz?a|{pY0g> zG0nPJ99fpx&vAwU>_;W4pt4H|JRIo6Gw6kv^@{X)5>LtE%%O&fZy}~o%ZnHAM&o#z zBW&D{qMmhj?tL6z%{Ae}lj${1j#5E|ZRbe~h-cuV40VeqBmHxR1|?Kvsa--SOZ^gl z$dWgGDND`ynS5^2RckaX;ng)7l5lyAUY4M)(<>6pb()fJW1VItcsFuB?`+U(68_kr zX$b?@X-UGD*J*Kki%l{moZF6cA$f&K$FaGNOr delta 412 zcwT$j&VJw*8*hL&GYc032z)OKn8>Ta{0&H1^nt09@?h$+3B zVB`V|^fH=)>7$IsAbRs}#z!1r#sjXcoM6Tbkq{#= - + @@ -202,7 +202,7 @@ - + @@ -215,7 +215,7 @@ - + @@ -228,7 +228,7 @@ - + @@ -301,7 +301,7 @@ - + @@ -338,6 +338,16 @@ + + + + + + + + + + diff --git a/src/net/bionicmessage/funambol/admin/MultipleCalendarSourceAdminPanel.java b/src/net/bionicmessage/funambol/admin/MultipleCalendarSourceAdminPanel.java index 5a27aca..7747b38 100644 --- a/src/net/bionicmessage/funambol/admin/MultipleCalendarSourceAdminPanel.java +++ b/src/net/bionicmessage/funambol/admin/MultipleCalendarSourceAdminPanel.java @@ -86,6 +86,7 @@ public class MultipleCalendarSourceAdminPanel extends SourceManagementPanel { sourcesTable_label = new javax.swing.JLabel(); serverHost_label = new javax.swing.JLabel(); dualtodo = new javax.swing.JCheckBox(); + convertAlarms = new javax.swing.JCheckBox(); setLayout(new java.awt.BorderLayout()); @@ -168,12 +169,12 @@ public class MultipleCalendarSourceAdminPanel extends SourceManagementPanel { emailSubstitute.setText("Substitute username for email address on GroupDAV server"); // NOI18N emailSubstitute.setMargin(new java.awt.Insets(0, 0, 0, 0)); mainPanel.add(emailSubstitute); - emailSubstitute.setBounds(130, 460, 395, 20); + emailSubstitute.setBounds(130, 480, 395, 20); zideStore.setText("OGo / multi timezone all day event handling"); // NOI18N zideStore.setMargin(new java.awt.Insets(0, 0, 0, 0)); mainPanel.add(zideStore); - zideStore.setBounds(130, 480, 390, 18); + zideStore.setBounds(130, 500, 390, 18); saveButton.setText("Save configuration"); // NOI18N saveButton.addActionListener(new java.awt.event.ActionListener() { @@ -182,7 +183,7 @@ public class MultipleCalendarSourceAdminPanel extends SourceManagementPanel { } }); mainPanel.add(saveButton); - saveButton.setBounds(440, 510, 157, 30); + saveButton.setBounds(430, 540, 157, 30); default_note.setText("NOTE: there MUST be a 'default' source. Use %USER% for OGo multiuser "); // NOI18N mainPanel.add(default_note); @@ -210,7 +211,7 @@ public class MultipleCalendarSourceAdminPanel extends SourceManagementPanel { versionLabel.setFont(new java.awt.Font("Lucida Grande", 0, 11)); versionLabel.setText("%_connector_version_%"); // NOI18N mainPanel.add(versionLabel); - versionLabel.setBounds(130, 500, 180, 14); + versionLabel.setBounds(130, 550, 180, 14); sourcesTable_label.setText("Calendar sources"); // NOI18N mainPanel.add(sourcesTable_label); @@ -229,6 +230,10 @@ public class MultipleCalendarSourceAdminPanel extends SourceManagementPanel { mainPanel.add(dualtodo); dualtodo.setBounds(130, 360, 350, 22); + convertAlarms.setText("Convert alarms (use with EXTREME caution)"); + mainPanel.add(convertAlarms); + convertAlarms.setBounds(130, 460, 310, 20); + scrollPane.setViewportView(mainPanel); add(scrollPane, java.awt.BorderLayout.CENTER); @@ -271,6 +276,9 @@ private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI if (zideStore.isSelected()) { sourceSettings.setProperty(Constants.UTC_RELATIVE_ALLDAY, "true"); } + if (convertAlarms.isSelected()) { + sourceSettings.setProperty(Constants.CONVERT_ALARMS,"true"); + } if (getState() == STATE_INSERT) { this.actionPerformed(new ActionEvent(this, ACTION_EVENT_INSERT, evt.getActionCommand())); } else { @@ -326,12 +334,16 @@ private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI if (sourceSettings.getProperty(Constants.UTC_RELATIVE_ALLDAY) != null) { zideStore.setSelected(true); } + if (sourceSettings.getProperty(Constants.CONVERT_ALARMS) != null) { + convertAlarms.setSelected(true); + } } versionLabel.setText(BVersion.version); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTextField cdataType; private javax.swing.JLabel cdataType_label; + private javax.swing.JCheckBox convertAlarms; private javax.swing.JLabel default_note; private javax.swing.JCheckBox dualtodo; private javax.swing.JCheckBox emailSubstitute; diff --git a/src/net/bionicmessage/funambol/datakit/funambol2ical4j.java b/src/net/bionicmessage/funambol/datakit/funambol2ical4j.java index 89f4cd0..9d58d6f 100644 --- a/src/net/bionicmessage/funambol/datakit/funambol2ical4j.java +++ b/src/net/bionicmessage/funambol/datakit/funambol2ical4j.java @@ -14,7 +14,6 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ - /** * Converts Funambol calendar instances to ical4j * @author matt @@ -32,6 +31,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Properties; import java.util.TimeZone; +import java.util.logging.Level; import java.util.logging.Logger; import net.bionicmessage.funambol.framework.Constants; import net.bionicmessage.funambol.framework.ObjectTransformationException; @@ -45,10 +45,9 @@ public class funambol2ical4j { public static Logger log = Logger.getLogger("groupdav.fnblical"); - public static net.fortuna.ical4j.model.Calendar - convertFunambolEvent2ical4jEvent( - com.funambol.common.pim.calendar.Calendar fnblcal, - Properties props, + public static net.fortuna.ical4j.model.Calendar convertFunambolEvent2ical4jEvent( + com.funambol.common.pim.calendar.Calendar fnblcal, + Properties props, SyncContext ctx) throws ObjectTransformationException { /* Do the same thing here as we did in ical4j2funambol. Pick out each * property we want and process it one by one */ @@ -63,9 +62,9 @@ public class funambol2ical4j { ical4jcal.getComponents().add(cc); /* if (props != null && props.getProperty("connector.timezone") != null) - tid = attachVTimeZone( - props.getProperty("connector.timezone"), - ical4jcal); */ + tid = attachVTimeZone( + props.getProperty("connector.timezone"), + ical4jcal); */ String tz = null; if (ctx.getPrincipal().getDevice().getConvertDatePolicy() == 0) { tz = ctx.getPrincipal().getDevice().getTimeZone(); @@ -86,9 +85,9 @@ public class funambol2ical4j { /* com.funambol.common.pim.common.Property clazz = fnblevent.getClassEvent(); if (clazz.getPropertyValue() != null) { - net.fortuna.ical4j.model.property.Clazz ical4jclazz = - new net.fortuna.ical4j.model.property.Clazz(clazz.getPropertyValueAsString()); - ical4jevent.getProperties().add(ical4jclazz); + net.fortuna.ical4j.model.property.Clazz ical4jclazz = + new net.fortuna.ical4j.model.property.Clazz(clazz.getPropertyValueAsString()); + ical4jevent.getProperties().add(ical4jclazz); } */ if (hasValue(dtstart)) { @@ -113,7 +112,7 @@ public class funambol2ical4j { cc.getProperties().add(dts); } catch (Exception ex) { log.severe("Error thrown in dtstart conversion: " + ex.getMessage()); - throw new ObjectTransformationException("Error in DTSTART conversion",ex); + throw new ObjectTransformationException("Error in DTSTART conversion", ex); } } @@ -121,7 +120,7 @@ public class funambol2ical4j { try { String dtenddate = dtend.getPropertyValueAsString(); /* CHECK: Funambol rolls dtend back if dtend(value=date) - &&dtstart(value==date). If Funambol has rolled them back, stop it here */ + &&dtstart(value==date). If Funambol has rolled them back, stop it here */ if (dtenddate.length() == com.funambol.common.pim.utility.TimeUtils.PATTERN_YYYY_MM_DD_LENGTH) { if (dtstart.getPropertyValueAsString().equals(dtenddate)) { String rolledUp = TimeUtils.rollOneDay(dtenddate, true); @@ -145,7 +144,7 @@ public class funambol2ical4j { } cc.getProperties().add(dte); } catch (Exception ex) { - throw new ObjectTransformationException("Error caught in dtend conversion",ex); + throw new ObjectTransformationException("Error caught in dtend conversion", ex); } } com.funambol.common.pim.common.Property summ = calcontent.getSummary(); @@ -252,10 +251,26 @@ public class funambol2ical4j { // If we have DTEND instead of DUE, swap if (dte != null) { cc.getProperties().remove(dte); - net.fortuna.ical4j.model.property.Due due = + net.fortuna.ical4j.model.property.Due due = new net.fortuna.ical4j.model.property.Due(dte.getDate()); cc.getProperties().add(due); } + + } + if (props.getProperty(Constants.CONVERT_ALARMS) != null) { + com.funambol.common.pim.common.Property dalarm = calcontent.getDAlarm(); + if (hasValue(dalarm)) { + try { + String[] attributes = dalarm.getPropertyValueAsString().split(";"); + String dt = attributes[0]; + if (!dt.contains("Z")) { + dt = dt.concat("Z"); + } + attachVAlarm(dt, 0, cc, tz); + } catch (ParseException ex) { + Logger.getLogger(funambol2ical4j.class.getName()).log(Level.SEVERE, null, ex); + } + } } return ical4jcal; } @@ -339,10 +354,37 @@ public class funambol2ical4j { } return null; } + + public static void attachVAlarm(String atTime, + int type, + net.fortuna.ical4j.model.component.CalendarComponent toAttach, + String tz) throws ParseException { + net.fortuna.ical4j.model.component.VAlarm vl = + new net.fortuna.ical4j.model.component.VAlarm(); + if (type ==0) { //display alarm + vl.getProperties().add(net.fortuna.ical4j.model.property.Action.DISPLAY); + } + net.fortuna.ical4j.model.DateTime triggerTime = parseIntoDateTime(atTime, tz); + net.fortuna.ical4j.model.property.Trigger trigger= new net.fortuna.ical4j.model.property.Trigger(triggerTime); + vl.getProperties().add(trigger); + net.fortuna.ical4j.model.property.Description alarmDescription = + new net.fortuna.ical4j.model.property.Description("Event reminder"); + vl.getProperties().add(alarmDescription); + if (toAttach instanceof net.fortuna.ical4j.model.component.VEvent) { + net.fortuna.ical4j.model.component.VEvent ve = + (net.fortuna.ical4j.model.component.VEvent)toAttach; + ve.getAlarms().add(vl); + } else if (toAttach instanceof net.fortuna.ical4j.model.component.VToDo) { + net.fortuna.ical4j.model.component.VToDo vt = + (net.fortuna.ical4j.model.component.VToDo)toAttach; + vt.getAlarms().add(vl); + } + } private static boolean hasValue(com.funambol.common.pim.common.Property prop) { if (prop != null && prop.getPropertyValueAsString() != null && - prop.getPropertyValueAsString().length() > 0) + prop.getPropertyValueAsString().length() > 0) { return true; + } return false; } } diff --git a/src/net/bionicmessage/funambol/datakit/ical4j2funambol.java b/src/net/bionicmessage/funambol/datakit/ical4j2funambol.java index d712b21..a192245 100644 --- a/src/net/bionicmessage/funambol/datakit/ical4j2funambol.java +++ b/src/net/bionicmessage/funambol/datakit/ical4j2funambol.java @@ -27,16 +27,23 @@ import net.fortuna.ical4j.model.Property.*; import net.fortuna.ical4j.data.*; import java.util.ArrayList; +import java.util.Iterator; +import net.fortuna.ical4j.model.component.CalendarComponent; +import net.fortuna.ical4j.model.component.VAlarm; import net.fortuna.ical4j.model.component.VEvent; import net.fortuna.ical4j.model.component.VToDo; import net.fortuna.ical4j.model.parameter.AltRep; import net.fortuna.ical4j.model.parameter.Encoding; +import net.fortuna.ical4j.model.parameter.Related; +import net.fortuna.ical4j.model.property.Action; import net.fortuna.ical4j.model.property.Categories; import net.fortuna.ical4j.model.property.Clazz; +import net.fortuna.ical4j.model.property.DateProperty; import net.fortuna.ical4j.model.property.Description; import net.fortuna.ical4j.model.property.DtEnd; import net.fortuna.ical4j.model.property.DtStart; import net.fortuna.ical4j.model.property.Due; +import net.fortuna.ical4j.model.property.Duration; import net.fortuna.ical4j.model.property.LastModified; import net.fortuna.ical4j.model.property.Location; import net.fortuna.ical4j.model.property.Priority; @@ -44,6 +51,7 @@ import net.fortuna.ical4j.model.property.RDate; import net.fortuna.ical4j.model.property.RRule; import net.fortuna.ical4j.model.property.Summary; import net.fortuna.ical4j.model.property.Transp; +import net.fortuna.ical4j.model.property.Trigger; import net.fortuna.ical4j.model.property.Uid; /** @@ -429,4 +437,63 @@ public class ical4j2funambol { e.setAllDay(true); } } + /** Process any alarms in the event/todo. Since this functionality is optional, + * it is in another function + */ + public static void attachAlarm(com.funambol.common.pim.calendar.CalendarContent e, + net.fortuna.ical4j.model.component.CalendarComponent ical4je) { + ComponentList alarms = null; + if (ical4je instanceof VEvent) { + VEvent ve = (VEvent) ical4je; + alarms = ve.getAlarms(); + } else if (ical4je instanceof VToDo) { + VToDo vt = (VToDo) ical4je; + alarms = vt.getAlarms(); + } else { + return; + } + Iterator alarmIterator = alarms.iterator(); + while (alarmIterator.hasNext()) { + VAlarm va = (VAlarm) alarmIterator.next(); + + Trigger t = va.getTrigger(); + String[] dalarmComponents = {"", "", "", ""}; + if (va.getAction().getValue().equals("DISPLAY")) { + if (t.getDateTime() != null) { + dalarmComponents[0] = t.getDateTime().toString(); + } else if (t.getDuration() != null) { + Dur dur = t.getDuration(); + DateProperty relatedTo = null; + if (t.getParameter(Related.RELATED) != null && + t.getParameter(Related.RELATED).equals(Related.END)) { + relatedTo = (DateProperty) ical4je.getProperty(DtEnd.DTEND); + } else { + relatedTo = (DateProperty) ical4je.getProperty(DtStart.DTSTART); + } + Date dt = relatedTo.getDate(); + // Calculate a new DateTime relative to dt + java.util.Calendar cal = java.util.Calendar.getInstance(); + cal.setTime(dt); + cal.add(java.util.Calendar.SECOND, -(dur.getSeconds())); + cal.add(java.util.Calendar.MINUTE, -(dur.getMinutes())); + cal.add(java.util.Calendar.HOUR, -(dur.getHours())); + cal.add(java.util.Calendar.DAY_OF_YEAR, -(dur.getDays())); + cal.add(java.util.Calendar.WEEK_OF_YEAR, -(dur.getWeeks())); + DateTime newDate = new DateTime(cal.getTime()); + newDate.setUtc(true); + dalarmComponents[0] = newDate.toString(); + } + } + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < dalarmComponents.length; i++) { + if (dalarmComponents[i] != null) { + buf.append(dalarmComponents[i]); + } + if (dalarmComponents.length != i - 1) { + buf.append(";"); + } + } + e.setDAlarm(new com.funambol.common.pim.common.Property(buf.toString())); + } + } } diff --git a/src/net/bionicmessage/funambol/framework/Constants.java b/src/net/bionicmessage/funambol/framework/Constants.java index b0347fe..81df043 100644 --- a/src/net/bionicmessage/funambol/framework/Constants.java +++ b/src/net/bionicmessage/funambol/framework/Constants.java @@ -49,6 +49,8 @@ public class Constants { public static final String MIXED_MODE = "connector.mixedmode"; /** connector.utcrelativeallday */ public static final String UTC_RELATIVE_ALLDAY = "connector.utcrelativeallday"; + /** connector.convertalarms */ + public static final String CONVERT_ALARMS = "connector.convertalarms"; /** */ public static final String INBOUND_PROCESSOR = ""; diff --git a/src/net/bionicmessage/funambol/framework/SourceObject.java b/src/net/bionicmessage/funambol/framework/SourceObject.java index 60001f1..52938c4 100644 --- a/src/net/bionicmessage/funambol/framework/SourceObject.java +++ b/src/net/bionicmessage/funambol/framework/SourceObject.java @@ -15,6 +15,9 @@ * along with this program. If not, see . */ package net.bionicmessage.funambol.framework; + +import java.util.Properties; + /** *
    SourceObject represents a PDI object as it passes through * from diff --git a/src/net/bionicmessage/funambol/groupdav/calendar/CalendarSyncSource.java b/src/net/bionicmessage/funambol/groupdav/calendar/CalendarSyncSource.java index 3607033..6495c4e 100644 --- a/src/net/bionicmessage/funambol/groupdav/calendar/CalendarSyncSource.java +++ b/src/net/bionicmessage/funambol/groupdav/calendar/CalendarSyncSource.java @@ -227,6 +227,7 @@ public class CalendarSyncSource extends AbstractSyncSource implements LazyInitBe try { Calendar object = so.getObjectFromStore(uid); OutboundFunambolCalendarObject ofc = new OutboundFunambolCalendarObject(object); + ofc.setConnectorProperties(this.getConnectorProperties()); SyncItem si = ofc.generateSyncItem(this); si.setState(getStateForItem(syncItemKey)); si.setType(this.getType()); diff --git a/src/net/bionicmessage/funambol/groupdav/calendar/InboundFunambolCalendarObject.java b/src/net/bionicmessage/funambol/groupdav/calendar/InboundFunambolCalendarObject.java index 866531d..8afb4bf 100644 --- a/src/net/bionicmessage/funambol/groupdav/calendar/InboundFunambolCalendarObject.java +++ b/src/net/bionicmessage/funambol/groupdav/calendar/InboundFunambolCalendarObject.java @@ -47,6 +47,10 @@ import net.fortuna.ical4j.model.property.DtEnd; import net.fortuna.ical4j.model.property.DtStart; import net.fortuna.ical4j.model.property.Summary; import net.fortuna.ical4j.model.property.Uid; +/** InboundFunambolCalendarObject represents an event/todo being processed + * by the sync source for addition to the server + * @author matt + */ public class InboundFunambolCalendarObject extends iCalSourceObject implements InboundObject { String destinationStore = "default"; Calendar ical2data = null; @@ -59,9 +63,7 @@ public class InboundFunambolCalendarObject extends iCalSourceObject implements I Properties connectorProperties = null; String uid = null; - // - // #[regen=yes,id=DCE.A367FEEC-E4A4-7876-9D7D-F062442C95A6] - // + public InboundFunambolCalendarObject (SyncItem item) { this.item = item; } @@ -178,12 +180,6 @@ public class InboundFunambolCalendarObject extends iCalSourceObject implements I public SyncContext getSyncContext() { return ctx; } - public void setConnectorProperties(Properties prop) { - this.connectorProperties = prop; - } - public Properties getConnectorProperties() { - return this.connectorProperties; - } public String getUID() { Component firstComponent = (Component) ical2data.getComponents().get(0); Uid ui = (Uid) firstComponent.getProperty(Uid.UID); @@ -253,5 +249,6 @@ public class InboundFunambolCalendarObject extends iCalSourceObject implements I this.getPIMComponent().getProperties().add(organizer); } } + } diff --git a/src/net/bionicmessage/funambol/groupdav/calendar/OutboundFunambolCalendarObject.java b/src/net/bionicmessage/funambol/groupdav/calendar/OutboundFunambolCalendarObject.java index f759029..2d94929 100644 --- a/src/net/bionicmessage/funambol/groupdav/calendar/OutboundFunambolCalendarObject.java +++ b/src/net/bionicmessage/funambol/groupdav/calendar/OutboundFunambolCalendarObject.java @@ -27,6 +27,7 @@ import net.bionicmessage.funambol.datakit.ical4j2funambol; import net.bionicmessage.funambol.framework.Constants; import net.bionicmessage.funambol.framework.ObjectTransformationException; import net.fortuna.ical4j.model.Calendar; +import net.fortuna.ical4j.model.component.CalendarComponent; /** OutboundFunambolCalendarObject handles the lifecycle of a calendar * event/task being sent to a device. @@ -92,6 +93,7 @@ public class OutboundFunambolCalendarObject extends iCalSourceObject implements public String getStringRepresentation(String type) throws ObjectTransformationException { try { cal = ical4j2funambol.convertIcal4jToFunambolEvent(ical2, type); + processAlarms(); if (type.equals(Constants.TYPE_CALENDAR_VCAL)) { VCalendarConverter cve = new VCalendarConverter(null, "UTF-8"); VCalendar vc = cve.calendar2vcalendar(cal, true); @@ -148,5 +150,17 @@ public class OutboundFunambolCalendarObject extends iCalSourceObject implements si.setContent(con); return si; } - + /** + * Process alarms embedded in the icalendar data for possible addition + * on the device. As this has dangerous ramifications in certain environments, + * it is disabled by default. When the Constants.CONVERT_ALARMS property is enabled, + * the connector will process alarms. To customize this functionality, override + * this function + */ + protected void processAlarms() throws ObjectTransformationException { + if (connectorProperties.getProperty(Constants.CONVERT_ALARMS) != null) { + ical4j2funambol.attachAlarm(cal.getCalendarContent(), + (CalendarComponent)ical2.getComponents().get(0)); + } + } } diff --git a/src/net/bionicmessage/funambol/groupdav/calendar/iCalSourceObject.java b/src/net/bionicmessage/funambol/groupdav/calendar/iCalSourceObject.java index ef0ce2d..f039fd3 100644 --- a/src/net/bionicmessage/funambol/groupdav/calendar/iCalSourceObject.java +++ b/src/net/bionicmessage/funambol/groupdav/calendar/iCalSourceObject.java @@ -17,6 +17,7 @@ */ package net.bionicmessage.funambol.groupdav.calendar; +import java.util.Properties; import net.bionicmessage.funambol.framework.ObjectTransformationException; import net.bionicmessage.funambol.framework.SourceObject; @@ -25,6 +26,7 @@ import net.bionicmessage.funambol.framework.SourceObject; // public class iCalSourceObject implements SourceObject { + protected Properties connectorProperties; // // #[regen=yes,id=DCE.C24B1B66-690F-D987-1127-E2226CD6621C] // @@ -113,5 +115,14 @@ public class iCalSourceObject implements SourceObject { return null; } + public void setConnectorProperties(Properties properties) { + this.connectorProperties = properties; + } + + public Properties getConnectorProperties() { + return this.connectorProperties; + } + + } diff --git a/src/net/bionicmessage/funambol/groupdav/contacts/InboundFunambolContactObject.java b/src/net/bionicmessage/funambol/groupdav/contacts/InboundFunambolContactObject.java index a00c9e5..16c9c7a 100644 --- a/src/net/bionicmessage/funambol/groupdav/contacts/InboundFunambolContactObject.java +++ b/src/net/bionicmessage/funambol/groupdav/contacts/InboundFunambolContactObject.java @@ -21,6 +21,7 @@ */ package net.bionicmessage.funambol.groupdav.contacts; +import java.util.Properties; import net.bionicmessage.funambol.framework.InboundObject; //import com.funambol.common.pim.contact.*; //import com.funambol.common.pim.converter.ContactToSIFC; @@ -49,7 +50,7 @@ public class InboundFunambolContactObject implements InboundObject { private ContactSyncSource css = null; private String uid = null; private SyncItem origItem; - + public InboundFunambolContactObject() { } @@ -142,8 +143,12 @@ public class InboundFunambolContactObject implements InboundObject { public String getDefaultStringOutputType() { return Constants.TYPE_CONTACT_VCARD21; } - + /** + * Return the vcard display name for this contact + * @return A String with the VCard Display Name. + */ public String getObjectName() { return contactObject.getName().getDisplayName().getPropertyValueAsString(); } + } diff --git a/test_src/net/bionicmessage/funambol/datakit/ical4j2funambolTest.java b/test_src/net/bionicmessage/funambol/datakit/ical4j2funambolTest.java index 80c240b..d4bf175 100644 --- a/test_src/net/bionicmessage/funambol/datakit/ical4j2funambolTest.java +++ b/test_src/net/bionicmessage/funambol/datakit/ical4j2funambolTest.java @@ -2,7 +2,6 @@ * To change this template, choose Tools | Templates * and open the template in the editor. */ - package net.bionicmessage.funambol.datakit; import com.funambol.common.pim.converter.VCalendarConverter; @@ -11,6 +10,7 @@ import java.io.File; import java.io.FileInputStream; import net.fortuna.ical4j.data.CalendarBuilder; import net.fortuna.ical4j.model.Calendar; +import net.fortuna.ical4j.model.component.CalendarComponent; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -48,17 +48,36 @@ public class ical4j2funambolTest { */ @Test public void convertIcal4jToFunambolEvent() throws Exception { - File testFile = new File ("doc/problem-samples/ogo-allday.ics"); + File testFile = new File("doc/problem-samples/ogo-allday.ics"); + FileInputStream fis = new FileInputStream(testFile); + CalendarBuilder cbuild = new CalendarBuilder(); + Calendar cal = cbuild.build(fis); + com.funambol.common.pim.calendar.Calendar fnblcal = + ical4j2funambol.convertIcal4jToFunambolEvent(cal, "text/x-vcalendar"); + VCalendarConverter vcc = new VCalendarConverter(null, "UTF-8"); + VCalendar vc = vcc.calendar2vcalendar(fnblcal, false); + String text = vc.toString(); + System.out.println(text); + + } + + /** Test attaching alarm + * + */ + @Test + public void testAlarmDurationM15() throws Exception { + File testFile = new File("doc/testData/korganizer-15min-alarm.ics"); FileInputStream fis = new FileInputStream(testFile); CalendarBuilder cbuild = new CalendarBuilder(); Calendar cal = cbuild.build(fis); - com.funambol.common.pim.calendar.Calendar fnblcal = + com.funambol.common.pim.calendar.Calendar fnblcal = ical4j2funambol.convertIcal4jToFunambolEvent(cal, "text/x-vcalendar"); + ical4j2funambol.attachAlarm(fnblcal.getCalendarContent(), + (CalendarComponent)cal.getComponents().get(0)); VCalendarConverter vcc = new VCalendarConverter(null, "UTF-8"); VCalendar vc = vcc.calendar2vcalendar(fnblcal, false); String text = vc.toString(); System.out.println(text); - } /** @@ -74,7 +93,4 @@ public class ical4j2funambolTest { @Test public void attachAllDayDtStart() { } - - - -} \ No newline at end of file +} diff --git a/test_src/net/bionicmessage/funambol/groupdav/contacts/ContactSyncSourceTest.java b/test_src/net/bionicmessage/funambol/groupdav/contacts/ContactSyncSourceTest.java index 282d062..4a433fa 100644 --- a/test_src/net/bionicmessage/funambol/groupdav/contacts/ContactSyncSourceTest.java +++ b/test_src/net/bionicmessage/funambol/groupdav/contacts/ContactSyncSourceTest.java @@ -49,7 +49,7 @@ import net.bionicmessage.funambol.groupdav.contacts.ContactSyncSourceTest; public class ContactSyncSourceTest { private String clientId = "STATIC-TEST"; - private String testPropertiesFile = ".groupdavconnector_test_properties"; + private String testPropertiesFile = ".groupdavconnector_addr_test_properties"; private ContactSyncSource css = null; private SyncContext ctx = null; private Sync4jPrincipal spp = null; -- 2.11.4.GIT