use of net.fortuna.ical4j.model.component.VAlarm in project bw-calendar-engine by Bedework.
the class VAlarmUtil method processComponentAlarms.
/**
* If there are any alarms for this component add them to the events alarm
* collection
*
* @param cb IcalCallback object
* @param val
* @param ev
* @param currentPrincipal - href for current authenticated user
* @param chg
* @throws CalFacadeException
*/
public static void processComponentAlarms(final IcalCallback cb, final Component val, final BwEvent ev, final String currentPrincipal, final ChangeTable chg) throws CalFacadeException {
try {
ComponentList als = null;
if (val instanceof VEvent) {
als = ((VEvent) val).getAlarms();
} else if (val instanceof VToDo) {
als = ((VToDo) val).getAlarms();
} else if (val instanceof VPoll) {
als = ((VPoll) val).getAlarms();
} else {
return;
}
if ((als == null) || als.isEmpty()) {
return;
}
for (Object o : als) {
if (!(o instanceof VAlarm)) {
throw new IcalMalformedException("Invalid alarm list");
}
VAlarm va = (VAlarm) o;
PropertyList pl = va.getProperties();
if (pl == null) {
// Empty VAlarm
throw new IcalMalformedException("Invalid alarm list");
}
Property prop;
BwAlarm al;
/* XXX Handle mozilla alarm stuff in a way that might work better with other clients.
*
*/
prop = pl.getProperty("X-MOZ-LASTACK");
boolean mozlastAck = prop != null;
String mozSnoozeTime = null;
if (mozlastAck) {
prop = pl.getProperty("X-MOZ-SNOOZE-TIME");
if (prop == null) {
// lastack and no snooze - presume dismiss so delete alarm
continue;
}
// UTC time
mozSnoozeTime = prop.getValue();
}
// All alarm types require action and trigger
prop = pl.getProperty(Property.ACTION);
if (prop == null) {
throw new IcalMalformedException("Invalid alarm");
}
String actionStr = prop.getValue();
TriggerVal tr = getTrigger(pl, "NONE".equals(actionStr));
if (mozSnoozeTime != null) {
tr.trigger = mozSnoozeTime;
tr.triggerDateTime = true;
tr.triggerStart = false;
}
DurationRepeat dr = getDurationRepeat(pl);
if ("EMAIL".equals(actionStr)) {
al = BwAlarm.emailAlarm(ev, ev.getCreatorHref(), tr, dr.duration, dr.repeat, getOptStr(pl, "ATTACH"), getReqStr(pl, "DESCRIPTION"), getReqStr(pl, "SUMMARY"), null);
Iterator<?> atts = getReqStrs(pl, "ATTENDEE");
while (atts.hasNext()) {
al.addAttendee(getAttendee(cb, (Attendee) atts.next()));
}
} else if ("AUDIO".equals(actionStr)) {
al = BwAlarm.audioAlarm(ev, ev.getCreatorHref(), tr, dr.duration, dr.repeat, getOptStr(pl, "ATTACH"));
} else if ("DISPLAY".equals(actionStr)) {
al = BwAlarm.displayAlarm(ev, ev.getCreatorHref(), tr, dr.duration, dr.repeat, getReqStr(pl, "DESCRIPTION"));
} else if ("PROCEDURE".equals(actionStr)) {
al = BwAlarm.procedureAlarm(ev, ev.getCreatorHref(), tr, dr.duration, dr.repeat, getReqStr(pl, "ATTACH"), getOptStr(pl, "DESCRIPTION"));
} else if ("NONE".equals(actionStr)) {
al = BwAlarm.noneAlarm(ev, ev.getCreatorHref(), tr, dr.duration, dr.repeat, getOptStr(pl, "DESCRIPTION"));
} else {
al = BwAlarm.otherAlarm(ev, ev.getCreatorHref(), actionStr, tr, dr.duration, dr.repeat, getOptStr(pl, "DESCRIPTION"));
}
/* Mozilla is add xprops to the containing event to set the snooze time.
* Seems wrong - there could be multiple alarms.
*
* We possibly want to try this sort of trick..
prop = pl.getProperty("X-MOZ-LASTACK");
boolean mozlastAck = prop != null;
String mozSnoozeTime = null;
if (mozlastAck) {
prop = pl.getProperty("X-MOZ-SNOOZE-TIME");
if (prop == null) {
// lastack and no snooze - presume dismiss so delete alarm
continue;
}
mozSnoozeTime = prop.getValue(); // UTC time
}
...
TriggerVal tr = getTrigger(pl);
if (mozSnoozeTime != null) {
tr.trigger = mozSnoozeTime;
tr.triggerDateTime = true;
tr.triggerStart = false;
}
*/
Iterator it = pl.iterator();
while (it.hasNext()) {
prop = (Property) it.next();
if (prop instanceof XProperty) {
/* ------------------------- x-property --------------------------- */
XProperty xp = (XProperty) prop;
al.addXproperty(new BwXproperty(xp.getName(), xp.getParameters().toString(), xp.getValue()));
continue;
}
if (prop instanceof Uid) {
Uid p = (Uid) prop;
al.addXproperty(BwXproperty.makeIcalProperty(p.getName(), p.getParameters().toString(), p.getValue()));
continue;
}
}
al.setEvent(ev);
al.setOwnerHref(currentPrincipal);
chg.addValue(PropertyInfoIndex.VALARM, al);
}
} catch (CalFacadeException cfe) {
throw cfe;
} catch (Throwable t) {
throw new CalFacadeException(t);
}
}
use of net.fortuna.ical4j.model.component.VAlarm in project bw-calendar-engine by Bedework.
the class VAlarmUtil method setAlarm.
private static VAlarm setAlarm(final BwEvent ev, final BwAlarm val) throws CalFacadeException {
try {
VAlarm alarm = new VAlarm();
int atype = val.getAlarmType();
String action;
if (atype != BwAlarm.alarmTypeOther) {
action = BwAlarm.alarmTypes[atype];
} else {
List<BwXproperty> xps = val.getXicalProperties("ACTION");
action = xps.get(0).getValue();
}
addProperty(alarm, new Action(action));
if (val.getTriggerDateTime()) {
DateTime dt = new DateTime(val.getTrigger());
addProperty(alarm, new Trigger(dt));
} else {
Trigger tr = new Trigger(new Dur(val.getTrigger()));
if (!val.getTriggerStart()) {
addParameter(tr, Related.END);
} else {
// Not required - it's the default - but we fail some Cyrus tests otherwise
// Apparently Cyrus now handles the default state correctly
// addParameter(tr, Related.START);
}
addProperty(alarm, tr);
}
if (val.getDuration() != null) {
addProperty(alarm, new Duration(new Dur(val.getDuration())));
addProperty(alarm, new Repeat(val.getRepeat()));
}
if (atype == BwAlarm.alarmTypeAudio) {
if (val.getAttach() != null) {
addProperty(alarm, new Attach(new URI(val.getAttach())));
}
} else if (atype == BwAlarm.alarmTypeDisplay) {
// checkRequiredProperty(val.getDescription(), "alarm-description");
if (val.getDescription() != null) {
addProperty(alarm, new Description(val.getDescription()));
} else {
addProperty(alarm, new Description(ev.getSummary()));
}
} else if (atype == BwAlarm.alarmTypeEmail) {
if (val.getAttach() != null) {
addProperty(alarm, new Attach(new URI(val.getAttach())));
}
checkRequiredProperty(val.getDescription(), "alarm-description");
addProperty(alarm, new Description(val.getDescription()));
checkRequiredProperty(val.getSummary(), "alarm-summary");
addProperty(alarm, new Summary(val.getSummary()));
if (val.getNumAttendees() > 0) {
for (BwAttendee att : val.getAttendees()) {
addProperty(alarm, setAttendee(att));
}
}
} else if (atype == BwAlarm.alarmTypeProcedure) {
checkRequiredProperty(val.getAttach(), "alarm-attach");
addProperty(alarm, new Attach(new URI(val.getAttach())));
if (val.getDescription() != null) {
addProperty(alarm, new Description(val.getDescription()));
}
} else {
if (val.getDescription() != null) {
addProperty(alarm, new Description(val.getDescription()));
}
}
if (val.getNumXproperties() > 0) {
/* This event has x-props */
IcalUtil.xpropertiesToIcal(alarm.getProperties(), val.getXproperties());
}
return alarm;
} catch (CalFacadeException cfe) {
throw cfe;
} catch (Throwable t) {
throw new CalFacadeException(t);
}
}
use of net.fortuna.ical4j.model.component.VAlarm in project ofbiz-framework by apache.
the class ICalConverter method createAlarm.
protected static VAlarm createAlarm(GenericValue workEffortEventReminder) {
VAlarm alarm = null;
Timestamp reminderStamp = workEffortEventReminder.getTimestamp("reminderDateTime");
if (reminderStamp != null) {
alarm = new VAlarm(new DateTime(reminderStamp));
} else {
TimeDuration duration = TimeDuration.fromNumber(workEffortEventReminder.getLong("reminderOffset"));
alarm = new VAlarm(new Dur(duration.days(), duration.hours(), duration.minutes(), duration.seconds()));
}
return alarm;
}
use of net.fortuna.ical4j.model.component.VAlarm in project android by nextcloud.
the class SaveCalendar method convertFromDb.
private VEvent convertFromDb(Cursor cur, Calendar cal, DtStamp timestamp) {
Log_OC.d(TAG, "cursor: " + DatabaseUtils.dumpCurrentRowToString(cur));
if (hasStringValue(cur, Events.ORIGINAL_ID)) {
// FIXME: Support these edited instances
Log_OC.w(TAG, "Ignoring edited instance of a recurring event");
return null;
}
PropertyList l = new PropertyList();
l.add(timestamp);
copyProperty(l, Property.UID, cur, Events.UID_2445);
String summary = copyProperty(l, Property.SUMMARY, cur, Events.TITLE);
String description = copyProperty(l, Property.DESCRIPTION, cur, Events.DESCRIPTION);
String organizer = getString(cur, Events.ORGANIZER);
if (!TextUtils.isEmpty(organizer)) {
// incorrectly left it in the organizer column.
if (!organizer.startsWith("mailto:")) {
organizer = "mailto:" + organizer;
}
try {
l.add(new Organizer(organizer));
} catch (URISyntaxException ignored) {
if (!mFailedOrganisers.contains(organizer)) {
Log_OC.e(TAG, "Failed to create mailTo for organizer " + organizer);
mFailedOrganisers.add(organizer);
}
}
}
copyProperty(l, Property.LOCATION, cur, Events.EVENT_LOCATION);
copyEnumProperty(l, Property.STATUS, cur, Events.STATUS, STATUS_ENUM);
boolean allDay = TextUtils.equals(getString(cur, Events.ALL_DAY), "1");
boolean isTransparent;
DtEnd dtEnd = null;
if (allDay) {
// All day event
isTransparent = true;
Date start = getDateTime(cur, Events.DTSTART, null, null);
Date end = getDateTime(cur, Events.DTEND, null, null);
l.add(new DtStart(new Date(start)));
if (end != null) {
dtEnd = new DtEnd(new Date(end));
} else {
dtEnd = new DtEnd(utcDateFromMs(start.getTime() + DateUtils.DAY_IN_MILLIS));
}
l.add(dtEnd);
} else {
// Regular or zero-time event. Start date must be a date-time
Date startDate = getDateTime(cur, Events.DTSTART, Events.EVENT_TIMEZONE, cal);
l.add(new DtStart(startDate));
// Use duration if we have one, otherwise end date
if (hasStringValue(cur, Events.DURATION)) {
isTransparent = getString(cur, Events.DURATION).equals("PT0S");
if (!isTransparent) {
copyProperty(l, Property.DURATION, cur, Events.DURATION);
}
} else {
String endTz = Events.EVENT_END_TIMEZONE;
if (endTz == null) {
endTz = Events.EVENT_TIMEZONE;
}
Date end = getDateTime(cur, Events.DTEND, endTz, cal);
dtEnd = new DtEnd(end);
isTransparent = startDate.getTime() == end.getTime();
if (!isTransparent) {
l.add(dtEnd);
}
}
}
copyEnumProperty(l, Property.CLASS, cur, Events.ACCESS_LEVEL, CLASS_ENUM);
int availability = getInt(cur, Events.AVAILABILITY);
if (availability > Events.AVAILABILITY_TENTATIVE) {
// Unknown/Invalid
availability = -1;
}
if (isTransparent) {
// not free, then mark it opaque.
if (availability >= 0 && availability != Events.AVAILABILITY_FREE) {
l.add(Transp.OPAQUE);
}
} else if (availability > Events.AVAILABILITY_BUSY) {
// This event is ordinarily busy but differs, so output a FREEBUSY
// period covering the time of the event
FreeBusy fb = new FreeBusy();
fb.getParameters().add(new FbType(AVAIL_ENUM.get(availability)));
DateTime start = new DateTime(((DtStart) l.getProperty(Property.DTSTART)).getDate());
if (dtEnd != null) {
fb.getPeriods().add(new Period(start, new DateTime(dtEnd.getDate())));
} else {
Duration d = (Duration) l.getProperty(Property.DURATION);
fb.getPeriods().add(new Period(start, d.getDuration()));
}
l.add(fb);
}
copyProperty(l, Property.RRULE, cur, Events.RRULE);
copyProperty(l, Property.RDATE, cur, Events.RDATE);
copyProperty(l, Property.EXRULE, cur, Events.EXRULE);
copyProperty(l, Property.EXDATE, cur, Events.EXDATE);
if (TextUtils.isEmpty(getString(cur, Events.CUSTOM_APP_PACKAGE))) {
// Only copy URL if there is no app i.e. we probably imported it.
copyProperty(l, Property.URL, cur, Events.CUSTOM_APP_URI);
}
VEvent e = new VEvent(l);
if (getInt(cur, Events.HAS_ALARM) == 1) {
// Add alarms
String s = summary == null ? (description == null ? "" : description) : summary;
Description desc = new Description(s);
ContentResolver resolver = activity.getContentResolver();
long eventId = getLong(cur, Events._ID);
Cursor alarmCur;
alarmCur = Reminders.query(resolver, eventId, mAllCols ? null : REMINDER_COLS);
while (alarmCur.moveToNext()) {
int mins = getInt(alarmCur, Reminders.MINUTES);
if (mins == -1) {
// FIXME: Get the real default
mins = 60;
}
// FIXME: We should support other types if possible
int method = getInt(alarmCur, Reminders.METHOD);
if (method == Reminders.METHOD_DEFAULT || method == Reminders.METHOD_ALERT) {
VAlarm alarm = new VAlarm(new Dur(0, 0, -mins, 0));
alarm.getProperties().add(Action.DISPLAY);
alarm.getProperties().add(desc);
e.getAlarms().add(alarm);
}
}
alarmCur.close();
}
return e;
}
use of net.fortuna.ical4j.model.component.VAlarm in project android by nextcloud.
the class ProcessVEvent method convertToDB.
// Munge a VEvent so Android won't reject it, then convert to ContentValues for inserting
private ContentValues convertToDB(VEvent e, Options options, List<Integer> reminders, long calendarId) {
reminders.clear();
boolean allDay = false;
boolean startIsDate = !(e.getStartDate().getDate() instanceof DateTime);
boolean isRecurring = hasProperty(e, Property.RRULE) || hasProperty(e, Property.RDATE);
if (startIsDate) {
// If the start date is a DATE we expect the end date to be a date too and the
// event is all-day, midnight to midnight (RFC 2445).
allDay = true;
}
if (!hasProperty(e, Property.DTEND) && !hasProperty(e, Property.DURATION)) {
// No end date or duration given.
// Since we added a duration above when the start date is a DATE:
// - The start date is a DATETIME, the event lasts no time at all (RFC 2445).
e.getProperties().add(ZERO_SECONDS);
// Zero time events are always free (RFC 2445), so override/set TRANSP accordingly.
removeProperty(e, Property.TRANSP);
e.getProperties().add(Transp.TRANSPARENT);
}
if (isRecurring) {
// Recurring event. Android insists on a duration.
if (!hasProperty(e, Property.DURATION)) {
// Calculate duration from start to end date
Duration d = new Duration(e.getStartDate().getDate(), e.getEndDate().getDate());
e.getProperties().add(d);
}
removeProperty(e, Property.DTEND);
} else {
// Non-recurring event. Android insists on an end date.
if (!hasProperty(e, Property.DTEND)) {
// Calculate end date from duration, set it and remove the duration.
e.getProperties().add(e.getEndDate());
}
removeProperty(e, Property.DURATION);
}
// Now calculate the db values for the event
ContentValues c = new ContentValues();
c.put(Events.CALENDAR_ID, calendarId);
copyProperty(c, Events.TITLE, e, Property.SUMMARY);
copyProperty(c, Events.DESCRIPTION, e, Property.DESCRIPTION);
if (e.getOrganizer() != null) {
URI uri = e.getOrganizer().getCalAddress();
try {
MailTo mailTo = MailTo.parse(uri.toString());
c.put(Events.ORGANIZER, mailTo.getTo());
// Ensure we can edit if not the organiser
c.put(Events.GUESTS_CAN_MODIFY, 1);
} catch (ParseException ignored) {
Log_OC.e(TAG, "Failed to parse Organiser URI " + uri.toString());
}
}
copyProperty(c, Events.EVENT_LOCATION, e, Property.LOCATION);
if (hasProperty(e, Property.STATUS)) {
String status = e.getProperty(Property.STATUS).getValue();
switch(status) {
case "TENTATIVE":
c.put(Events.STATUS, Events.STATUS_TENTATIVE);
break;
case "CONFIRMED":
c.put(Events.STATUS, Events.STATUS_CONFIRMED);
break;
case // NOTE: In ical4j it is CANCELLED with two L
"CANCELLED":
c.put(Events.STATUS, Events.STATUS_CANCELED);
break;
}
}
copyProperty(c, Events.DURATION, e, Property.DURATION);
if (allDay) {
c.put(Events.ALL_DAY, 1);
}
copyDateProperty(c, Events.DTSTART, Events.EVENT_TIMEZONE, e.getStartDate());
if (hasProperty(e, Property.DTEND)) {
copyDateProperty(c, Events.DTEND, Events.EVENT_END_TIMEZONE, e.getEndDate());
}
if (hasProperty(e, Property.CLASS)) {
String access = e.getProperty(Property.CLASS).getValue();
int accessLevel = Events.ACCESS_DEFAULT;
switch(access) {
case "CONFIDENTIAL":
accessLevel = Events.ACCESS_CONFIDENTIAL;
break;
case "PRIVATE":
accessLevel = Events.ACCESS_PRIVATE;
break;
case "PUBLIC":
accessLevel = Events.ACCESS_PUBLIC;
break;
}
c.put(Events.ACCESS_LEVEL, accessLevel);
}
// Work out availability. This is confusing as FREEBUSY and TRANSP overlap.
if (Events.AVAILABILITY != null) {
int availability = Events.AVAILABILITY_BUSY;
if (hasProperty(e, Property.TRANSP)) {
if (e.getTransparency() == Transp.TRANSPARENT) {
availability = Events.AVAILABILITY_FREE;
}
} else if (hasProperty(e, Property.FREEBUSY)) {
FreeBusy fb = (FreeBusy) e.getProperty(Property.FREEBUSY);
FbType fbType = (FbType) fb.getParameter(Parameter.FBTYPE);
if (fbType != null && fbType == FbType.FREE) {
availability = Events.AVAILABILITY_FREE;
} else if (fbType != null && fbType == FbType.BUSY_TENTATIVE) {
availability = Events.AVAILABILITY_TENTATIVE;
}
}
c.put(Events.AVAILABILITY, availability);
}
copyProperty(c, Events.RRULE, e, Property.RRULE);
copyProperty(c, Events.RDATE, e, Property.RDATE);
copyProperty(c, Events.EXRULE, e, Property.EXRULE);
copyProperty(c, Events.EXDATE, e, Property.EXDATE);
copyProperty(c, Events.CUSTOM_APP_URI, e, Property.URL);
copyProperty(c, Events.UID_2445, e, Property.UID);
if (c.containsKey(Events.UID_2445) && TextUtils.isEmpty(c.getAsString(Events.UID_2445))) {
// Remove null/empty UIDs
c.remove(Events.UID_2445);
}
for (Object alarm : e.getAlarms()) {
VAlarm a = (VAlarm) alarm;
if (a.getAction() != Action.AUDIO && a.getAction() != Action.DISPLAY) {
// Ignore email and procedure alarms
continue;
}
Trigger t = a.getTrigger();
final long startMs = e.getStartDate().getDate().getTime();
long alarmStartMs = startMs;
long alarmMs;
// - Check the calendars max number of alarms
if (t.getDateTime() != null) {
// Absolute
alarmMs = t.getDateTime().getTime();
} else if (t.getDuration() != null && t.getDuration().isNegative()) {
Related rel = (Related) t.getParameter(Parameter.RELATED);
if (rel != null && rel == Related.END) {
alarmStartMs = e.getEndDate().getDate().getTime();
}
// Relative
alarmMs = alarmStartMs - durationToMs(t.getDuration());
} else {
continue;
}
int reminder = (int) ((startMs - alarmMs) / DateUtils.MINUTE_IN_MILLIS);
if (reminder >= 0 && !reminders.contains(reminder)) {
reminders.add(reminder);
}
}
if (options.getReminders(reminders).size() > 0) {
c.put(Events.HAS_ALARM, 1);
}
// FIXME: Attendees, SELF_ATTENDEE_STATUS
return c;
}
Aggregations