Search in sources :

Example 36 with PropertyList

use of net.fortuna.ical4j.model.PropertyList in project bw-calendar-engine by Bedework.

the class BwEventUtil method toEvent.

/**
 * We are going to try to construct a BwEvent object from a VEvent. This
 * may represent a new event or an update to a pre-existing event. In any
 * case, the VEvent probably has insufficient information to completely
 * reconstitute the event object so we'll get the uid first and retrieve
 * the event if it exists.
 *
 * <p>To put it another way we're doing a diff then update.
 *
 * <p>If it doesn't exist, we'll first fill in the appropriate fields,
 * (non-public, creator, created etc) then for both cases update the
 * remaining fields from the VEvent.
 *
 * <p>Recurring events present some challenges. If there is no recurrence
 * id the vevent represents the master entity which defines the recurrence
 * rules. If a recurrence id is present then the vevent represents a
 * recurrence instance override and we should not attempt to retrieve the
 * actual object but the referenced instance.
 *
 * <p>Also, note that we sorted the components first so we get the master
 * before any instances.
 *
 * <p>If DTSTART, RRULE, EXRULE have changed (also RDATE, EXDATE?) then any
 * existing overrides are unusable. We should delete all overrides and replace
 * with new ones.
 *
 * <p>For an update we have to keep track of which fields were present in
 * the vevent and set all absent fields to null in the BwEvent.
 *
 * @param cb          IcalCallback object
 * @param cal         Needed so we can retrieve the event.
 * @param ical        Icalendar we are converting. We check its events for
 *                    overrides.
 * @param val         VEvent object
 * @param diff        True if we should assume we are updating existing events.
 * @param mergeAttendees True if we should only update our own attendee.
 * @return EventInfo  object representing new entry or updated entry
 * @throws CalFacadeException
 */
public static EventInfo toEvent(final IcalCallback cb, final BwCalendar cal, final Icalendar ical, final Component val, final boolean diff, final boolean mergeAttendees) throws CalFacadeException {
    if (val == null) {
        return null;
    }
    String currentPrincipal = null;
    final BwPrincipal principal = cb.getPrincipal();
    if (principal != null) {
        currentPrincipal = principal.getPrincipalRef();
    }
    final boolean debug = getLog().isDebugEnabled();
    @SuppressWarnings("unchecked") final Holder<Boolean> hasXparams = new Holder<Boolean>(Boolean.FALSE);
    final int methodType = ical.getMethodType();
    String attUri = null;
    if (mergeAttendees) {
        // We'll need this later.
        attUri = cb.getCaladdr(cb.getPrincipal().getPrincipalRef());
    }
    final String colPath;
    if (cal == null) {
        colPath = null;
    } else {
        colPath = cal.getPath();
    }
    try {
        final PropertyList pl = val.getProperties();
        boolean vpoll = false;
        if (pl == null) {
            // Empty component
            return null;
        }
        final int entityType;
        if (val instanceof VEvent) {
            entityType = IcalDefs.entityTypeEvent;
        } else if (val instanceof VToDo) {
            entityType = IcalDefs.entityTypeTodo;
        } else if (val instanceof VJournal) {
            entityType = IcalDefs.entityTypeJournal;
        } else if (val instanceof VFreeBusy) {
            entityType = IcalDefs.entityTypeFreeAndBusy;
        } else if (val instanceof VAvailability) {
            entityType = IcalDefs.entityTypeVavailability;
        } else if (val instanceof Available) {
            entityType = IcalDefs.entityTypeAvailable;
        } else if (val instanceof VPoll) {
            entityType = IcalDefs.entityTypeVpoll;
            vpoll = true;
        } else {
            throw new CalFacadeException("org.bedework.invalid.component.type", val.getName());
        }
        Property prop;
        // Get the guid from the component
        String guid = null;
        prop = pl.getProperty(Property.UID);
        if (prop != null) {
            testXparams(prop, hasXparams);
            guid = prop.getValue();
        }
        if (guid == null) {
            /* XXX A guid is required - but are there devices out there without a
         *       guid - and if so how do we handle it?
         */
            throw new CalFacadeException(CalFacadeException.noGuid);
        }
        /* See if we have a recurrence id */
        BwDateTime ridObj = null;
        String rid = null;
        prop = pl.getProperty(Property.RECURRENCE_ID);
        if (prop != null) {
            testXparams(prop, hasXparams);
            ridObj = BwDateTime.makeBwDateTime((DateProperty) prop);
            if (ridObj.getRange() != null) {
                /* XXX What do I do with it? */
                warn("TRANS-TO_EVENT: Got a recurrence id range");
            }
            rid = ridObj.getDate();
        }
        EventInfo masterEI = null;
        EventInfo evinfo = null;
        BwEvent ev = null;
        /* If we have a recurrence id see if we already have the master (we should
       * get a master + all its overrides).
       *
       * If so find the override and use the annnotation or if no override,
       * make one.
       *
       * If no override retrieve the event, add it to our table and then locate the
       * annotation.
       *
       * If there is no annotation, create one.
       *
       * It's possible we have been sent 'detached' instances of a recurring
       * event. This may happen if we are invited to one or more instances of a
       * meeting. In this case we try to retrieve the master and if it doesn't
       * exist we manufacture one. We consider such an instance an update to
       * that instance only and leave the others alone.
       */
        /* We need this in a couple of places */
        final DtStart dtStart = (DtStart) pl.getProperty(Property.DTSTART);
        /* If this is a recurrence instance see if we can find the master
       */
        if (rid != null) {
            // See if we have a new master event. If so create a proxy to this event.
            masterEI = findMaster(guid, ical.getComponents());
            if (masterEI != null) {
                evinfo = masterEI.findOverride(rid);
            }
        }
        if (diff && (evinfo == null) && (cal != null) && (cal.getCalType() != BwCalendar.calTypeInbox) && (cal.getCalType() != BwCalendar.calTypePendingInbox) && (cal.getCalType() != BwCalendar.calTypeOutbox)) {
            if (debug) {
                debugMsg("TRANS-TO_EVENT: try to fetch event with guid=" + guid);
            }
            final Collection<EventInfo> eis = cb.getEvent(colPath, guid);
            if (Util.isEmpty(eis)) {
            // do nothing
            } else if (eis.size() > 1) {
                // DORECUR - wrong again
                throw new CalFacadeException("More than one event returned for guid.");
            } else {
                evinfo = eis.iterator().next();
            }
            if (debug) {
                if (evinfo != null) {
                    debugMsg("TRANS-TO_EVENT: fetched event with guid");
                } else {
                    debugMsg("TRANS-TO_EVENT: did not find event with guid");
                }
            }
            if (evinfo != null) {
                if (rid != null) {
                    // We just retrieved it's master
                    masterEI = evinfo;
                    masterEI.setInstanceOnly(true);
                    evinfo = masterEI.findOverride(rid);
                    ical.addComponent(masterEI);
                } else if (methodType == ScheduleMethods.methodTypeCancel) {
                    // This should never have an rid for cancel of entire event.
                    evinfo.setInstanceOnly(evinfo.getEvent().getSuppressed());
                } else {
                    // Presumably sent an update for the entire event. No longer suppressed master
                    evinfo.getEvent().setSuppressed(false);
                }
            } else if (rid != null) {
                /* Manufacture a master for the instance */
                masterEI = makeNewEvent(cb, entityType, guid, colPath);
                final BwEvent e = masterEI.getEvent();
                // XXX This seems bogus
                final DtStart mdtStart;
                final String bogusDate = "19980118";
                final String bogusTime = "T230000";
                final Parameter par = dtStart.getParameter("VALUE");
                final boolean isDateType = (par != null) && (par.equals(Value.DATE));
                if (isDateType) {
                    mdtStart = new DtStart(new Date(bogusDate));
                } else if (dtStart.isUtc()) {
                    mdtStart = new DtStart(bogusDate + bogusTime + "Z");
                } else if (dtStart.getTimeZone() == null) {
                    mdtStart = new DtStart(bogusDate + bogusTime);
                } else {
                    mdtStart = new DtStart(bogusDate + bogusTime + "Z", dtStart.getTimeZone());
                }
                setDates(cb.getPrincipal().getPrincipalRef(), masterEI, mdtStart, null, null);
                e.setRecurring(true);
                // e.addRdate(ridObj);
                e.setSuppressed(true);
                ical.addComponent(masterEI);
                evinfo = masterEI.findOverride(rid);
                masterEI.setInstanceOnly(rid != null);
            }
        }
        if (evinfo == null) {
            evinfo = makeNewEvent(cb, entityType, guid, colPath);
        } else if (evinfo.getEvent().getEntityType() != entityType) {
            throw new CalFacadeException("org.bedework.mismatched.entity.type", val.toString());
        }
        final ChangeTable chg = evinfo.getChangeset(cb.getPrincipal().getPrincipalRef());
        if (rid != null) {
            final String evrid = evinfo.getEvent().getRecurrenceId();
            if ((evrid == null) || (!evrid.equals(rid))) {
                warn("Mismatched rid ev=" + evrid + " expected " + rid);
                // XXX spurious???
                chg.changed(PropertyInfoIndex.RECURRENCE_ID, evrid, rid);
            }
            if (masterEI.getEvent().getSuppressed()) {
                masterEI.getEvent().addRdate(ridObj);
            }
        }
        ev = evinfo.getEvent();
        ev.setScheduleMethod(methodType);
        DtEnd dtEnd = null;
        if (entityType == IcalDefs.entityTypeTodo) {
            final Due due = (Due) pl.getProperty(Property.DUE);
            if (due != null) {
                dtEnd = new DtEnd(due.getParameters(), due.getValue());
            }
        } else {
            dtEnd = (DtEnd) pl.getProperty(Property.DTEND);
        }
        final Duration duration = (Duration) pl.getProperty(Property.DURATION);
        setDates(cb.getPrincipal().getPrincipalRef(), evinfo, dtStart, dtEnd, duration);
        for (final Object aPl : pl) {
            prop = (Property) aPl;
            testXparams(prop, hasXparams);
            // debugMsg("ical prop " + prop.getClass().getName());
            String pval = prop.getValue();
            if ((pval != null) && (pval.length() == 0)) {
                pval = null;
            }
            final PropertyInfoIndex pi;
            if (prop instanceof XProperty) {
                pi = PropertyInfoIndex.XPROP;
            } else {
                pi = PropertyInfoIndex.fromName(prop.getName());
            }
            if (pi == null) {
                debugMsg("Unknown property with name " + prop.getName() + " class " + prop.getClass() + " and value " + pval);
                continue;
            }
            chg.present(pi);
            switch(pi) {
                case ACCEPT_RESPONSE:
                    /* ------------------- Accept Response -------------------- */
                    String sval = ((AcceptResponse) prop).getValue();
                    if (chg.changed(pi, ev.getPollAcceptResponse(), sval)) {
                        ev.setPollAcceptResponse(sval);
                    }
                    break;
                case ATTACH:
                    /* ------------------- Attachment -------------------- */
                    chg.addValue(pi, getAttachment((Attach) prop));
                    break;
                case ATTENDEE:
                    if (methodType == ScheduleMethods.methodTypePublish) {
                        if (cb.getStrictness() == IcalCallback.conformanceStrict) {
                            throw new CalFacadeException(CalFacadeException.attendeesInPublish);
                        }
                        if (cb.getStrictness() == IcalCallback.conformanceWarn) {
                        // warn("Had attendees for PUBLISH");
                        }
                    }
                    Attendee attPr = (Attendee) prop;
                    if (evinfo.getNewEvent() || !mergeAttendees) {
                        chg.addValue(pi, getAttendee(cb, attPr));
                    } else {
                        final String pUri = cb.getCaladdr(attPr.getValue());
                        if (pUri.equals(attUri)) {
                            /* Only update for our own attendee
               * We're doing a PUT and this must be the attendee updating their
               * partstat. We don't allow them to change other attendees
               * whatever the PUT content says.
               */
                            chg.addValue(pi, getAttendee(cb, attPr));
                        } else {
                            // Use the value we currently have
                            boolean found = false;
                            for (final BwAttendee att : ev.getAttendees()) {
                                if (pUri.equals(att.getAttendeeUri())) {
                                    chg.addValue(pi, att.clone());
                                    found = true;
                                    break;
                                }
                            }
                            if (!found) {
                                // An added attendee
                                final BwAttendee att = getAttendee(cb, attPr);
                                att.setPartstat(IcalDefs.partstatValNeedsAction);
                                chg.addValue(pi, att);
                            }
                        }
                    }
                    break;
                case BUSYTYPE:
                    int ibt = BwEvent.fromBusyTypeString(pval);
                    if (chg.changed(pi, ev.getBusyType(), ibt)) {
                        ev.setBusyType(ibt);
                    }
                    break;
                case CATEGORIES:
                    /* ------------------- Categories -------------------- */
                    Categories cats = (Categories) prop;
                    TextList cl = cats.getCategories();
                    String lang = getLang(cats);
                    if (cl != null) {
                        /* Got some categories */
                        Iterator cit = cl.iterator();
                        while (cit.hasNext()) {
                            String wd = (String) cit.next();
                            if (wd == null) {
                                continue;
                            }
                            BwString key = new BwString(lang, wd);
                            BwCategory cat = cb.findCategory(key);
                            if (cat == null) {
                                cat = BwCategory.makeCategory();
                                cat.setWord(key);
                                cb.addCategory(cat);
                            }
                            chg.addValue(pi, cat);
                        }
                    }
                    break;
                case CLASS:
                    if (chg.changed(pi, ev.getClassification(), pval)) {
                        ev.setClassification(pval);
                    }
                    break;
                case COMMENT:
                    /* ------------------- Comment -------------------- */
                    chg.addValue(pi, new BwString(null, pval));
                    break;
                case COMPLETED:
                    if (chg.changed(pi, ev.getCompleted(), pval)) {
                        ev.setCompleted(pval);
                    }
                    break;
                case CONTACT:
                    /* ------------------- Contact -------------------- */
                    String altrep = getAltRepPar(prop);
                    lang = getLang(prop);
                    String uid = getUidPar(prop);
                    BwString nm = new BwString(lang, pval);
                    BwContact contact = null;
                    if (uid != null) {
                        contact = cb.getContact(uid);
                    }
                    if (contact == null) {
                        contact = cb.findContact(nm);
                    }
                    if (contact == null) {
                        contact = BwContact.makeContact();
                        contact.setCn(nm);
                        contact.setLink(altrep);
                        cb.addContact(contact);
                    } else {
                        contact.setCn(nm);
                        contact.setLink(altrep);
                    }
                    chg.addValue(pi, contact);
                    break;
                case CREATED:
                    if (chg.changed(pi, ev.getCreated(), pval)) {
                        ev.setCreated(pval);
                    }
                    break;
                case DESCRIPTION:
                    if (chg.changed(pi, ev.getDescription(), pval)) {
                        ev.setDescription(pval);
                    }
                    break;
                case DTEND:
                    break;
                case DTSTAMP:
                    /* ------------------- DtStamp -------------------- */
                    ev.setDtstamp(pval);
                    break;
                case DTSTART:
                    break;
                case DURATION:
                    break;
                case EXDATE:
                    /* ------------------- ExDate -------------------- */
                    chg.addValues(pi, makeDateTimes((DateListProperty) prop));
                    break;
                case EXRULE:
                    /* ------------------- ExRule -------------------- */
                    chg.addValue(pi, pval);
                    break;
                case FREEBUSY:
                    /* ------------------- freebusy -------------------- */
                    FreeBusy fbusy = (FreeBusy) prop;
                    PeriodList perpl = fbusy.getPeriods();
                    Parameter par = getParameter(fbusy, "FBTYPE");
                    int fbtype;
                    if (par == null) {
                        fbtype = BwFreeBusyComponent.typeBusy;
                    } else if (par.equals(FbType.BUSY)) {
                        fbtype = BwFreeBusyComponent.typeBusy;
                    } else if (par.equals(FbType.BUSY_TENTATIVE)) {
                        fbtype = BwFreeBusyComponent.typeBusyTentative;
                    } else if (par.equals(FbType.BUSY_UNAVAILABLE)) {
                        fbtype = BwFreeBusyComponent.typeBusyUnavailable;
                    } else if (par.equals(FbType.FREE)) {
                        fbtype = BwFreeBusyComponent.typeFree;
                    } else {
                        if (debug) {
                            debugMsg("Unsupported parameter " + par.getName());
                        }
                        throw new IcalMalformedException("parameter " + par.getName());
                    }
                    BwFreeBusyComponent fbc = new BwFreeBusyComponent();
                    fbc.setType(fbtype);
                    Iterator perit = perpl.iterator();
                    while (perit.hasNext()) {
                        Period per = (Period) perit.next();
                        fbc.addPeriod(per);
                    }
                    ev.addFreeBusyPeriod(fbc);
                    break;
                case GEO:
                    /* ------------------- Geo -------------------- */
                    Geo g = (Geo) prop;
                    BwGeo geo = new BwGeo(g.getLatitude(), g.getLongitude());
                    if (chg.changed(pi, ev.getGeo(), geo)) {
                        ev.setGeo(geo);
                    }
                    break;
                case LAST_MODIFIED:
                    if (chg.changed(pi, ev.getLastmod(), pval)) {
                        ev.setLastmod(pval);
                    }
                    break;
                case LOCATION:
                    /* ------------------- Location -------------------- */
                    BwLocation loc = null;
                    // String uid = getUidPar(prop);
                    /* At the moment Mozilla lightning is broken and this leads to all
           * sorts of problems.
            if (uid != null) {
              loc = cb.getLocation(uid);
            }
           */
                    lang = getLang(prop);
                    BwString addr = null;
                    if (pval != null) {
                        if (loc == null) {
                            addr = new BwString(lang, pval);
                            loc = cb.findLocation(addr);
                        }
                        if (loc == null) {
                            loc = BwLocation.makeLocation();
                            loc.setAddress(addr);
                            cb.addLocation(loc);
                        }
                    }
                    BwLocation evloc = ev.getLocation();
                    if (chg.changed(pi, evloc, loc)) {
                        // CHGTBL - this only shows that it's a different location object
                        ev.setLocation(loc);
                    } else if ((loc != null) && (evloc != null)) {
                        // See if the value is changed
                        String evval = evloc.getAddress().getValue();
                        String inval = loc.getAddress().getValue();
                        if (!evval.equals(inval)) {
                            chg.changed(pi, evval, inval);
                            evloc.getAddress().setValue(inval);
                        }
                    }
                    break;
                case ORGANIZER:
                    /* ------------------- Organizer -------------------- */
                    final BwOrganizer org = getOrganizer(cb, (Organizer) prop);
                    final BwOrganizer evorg = ev.getOrganizer();
                    final BwOrganizer evorgCopy;
                    if (evorg == null) {
                        evorgCopy = null;
                    } else {
                        evorgCopy = (BwOrganizer) evorg.clone();
                    }
                    if (chg.changed(pi, evorgCopy, org)) {
                        if (evorg == null) {
                            ev.setOrganizer(org);
                        } else {
                            evorg.update(org);
                        }
                    }
                    break;
                case PERCENT_COMPLETE:
                    /* ------------------- PercentComplete -------------------- */
                    Integer ival = ((PercentComplete) prop).getPercentage();
                    if (chg.changed(pi, ev.getPercentComplete(), ival)) {
                        ev.setPercentComplete(ival);
                    }
                    break;
                case POLL_MODE:
                    /* ------------------- Poll mode -------------------- */
                    sval = ((PollMode) prop).getValue();
                    if (chg.changed(pi, ev.getPollMode(), sval)) {
                        ev.setPollMode(sval);
                    }
                    break;
                case POLL_PROPERTIES:
                    /* ------------------- Poll properties ---------------- */
                    sval = ((PollProperties) prop).getValue();
                    if (chg.changed(pi, ev.getPollProperties(), sval)) {
                        ev.setPollProperties(sval);
                    }
                    break;
                case POLL_WINNER:
                    /* ------------------- Poll winner -------------------- */
                    ival = ((PollWinner) prop).getPollwinner();
                    if (chg.changed(pi, ev.getPollWinner(), ival)) {
                        ev.setPollWinner(ival);
                    }
                    break;
                case PRIORITY:
                    /* ------------------- Priority -------------------- */
                    ival = ((Priority) prop).getLevel();
                    if (chg.changed(pi, ev.getPriority(), ival)) {
                        ev.setPriority(ival);
                    }
                    break;
                case RDATE:
                    /* ------------------- RDate -------------------- */
                    chg.addValues(pi, makeDateTimes((DateListProperty) prop));
                    break;
                case RECURRENCE_ID:
                    break;
                case RELATED_TO:
                    /* ------------------- RelatedTo -------------------- */
                    final RelatedTo irelto = (RelatedTo) prop;
                    final BwRelatedTo relto = new BwRelatedTo();
                    final String parval = IcalUtil.getParameterVal(irelto, "RELTYPE");
                    if (parval != null) {
                        relto.setRelType(parval);
                    }
                    relto.setValue(irelto.getValue());
                    if (chg.changed(pi, ev.getRelatedTo(), relto)) {
                        ev.setRelatedTo(relto);
                    }
                    break;
                case REQUEST_STATUS:
                    /* ------------------- RequestStatus -------------------- */
                    final BwRequestStatus rs = BwRequestStatus.fromRequestStatus((RequestStatus) prop);
                    chg.addValue(pi, rs);
                    break;
                case RESOURCES:
                    /* ------------------- Resources -------------------- */
                    final TextList rl = ((Resources) prop).getResources();
                    if (rl != null) {
                        /* Got some resources */
                        lang = getLang(prop);
                        Iterator rit = rl.iterator();
                        while (rit.hasNext()) {
                            BwString rsrc = new BwString(lang, (String) rit.next());
                            chg.addValue(pi, rsrc);
                        }
                    }
                    break;
                case RRULE:
                    /* ------------------- RRule -------------------- */
                    chg.addValue(pi, pval);
                    break;
                case SEQUENCE:
                    /* ------------------- Sequence -------------------- */
                    int seq = ((Sequence) prop).getSequenceNo();
                    if (seq != ev.getSequence()) {
                        chg.changed(pi, ev.getSequence(), seq);
                        ev.setSequence(seq);
                    }
                    break;
                case STATUS:
                    if (chg.changed(pi, ev.getStatus(), pval)) {
                        ev.setStatus(pval);
                    }
                    break;
                case SUMMARY:
                    if (chg.changed(pi, ev.getSummary(), pval)) {
                        ev.setSummary(pval);
                    }
                    break;
                case TRANSP:
                    if (chg.changed(pi, ev.getPeruserTransparency(cb.getPrincipal().getPrincipalRef()), pval)) {
                        BwXproperty pu = ev.setPeruserTransparency(cb.getPrincipal().getPrincipalRef(), pval);
                        if (pu != null) {
                            chg.addValue(PropertyInfoIndex.XPROP, pu);
                        }
                    }
                    break;
                case UID:
                    break;
                case URL:
                    if (chg.changed(pi, ev.getLink(), pval)) {
                        ev.setLink(pval);
                    }
                    break;
                case XPROP:
                    /* ------------------------- x-property --------------------------- */
                    final String name = prop.getName();
                    if (name.equalsIgnoreCase(BwXproperty.bedeworkCost)) {
                        if (chg.changed(PropertyInfoIndex.COST, ev.getCost(), pval)) {
                            ev.setCost(pval);
                        }
                        break;
                    }
                    if (name.equalsIgnoreCase(BwXproperty.xBedeworkCategories)) {
                        if (checkCategory(cb, chg, ev, null, pval)) {
                            break;
                        }
                    }
                    if (name.equalsIgnoreCase(BwXproperty.xBedeworkLocation)) {
                        if (checkLocation(cb, chg, ev, prop)) {
                            break;
                        }
                    }
                    if (name.equalsIgnoreCase(BwXproperty.xBedeworkContact)) {
                        if (checkContact(cb, chg, ev, null, pval)) {
                            break;
                        }
                    }
                    /* See if this is an x-category that can be
               converted to a real category
              */
                    final XProperty xp = (XProperty) prop;
                    chg.addValue(PropertyInfoIndex.XPROP, new BwXproperty(name, xp.getParameters().toString(), pval));
                    break;
                default:
                    if (debug) {
                        debugMsg("Unsupported property with index " + pi + "; class " + prop.getClass() + " and value " + pval);
                    }
            }
        }
        if (val instanceof VAvailability) {
            processAvailable(cb, cal, ical, (VAvailability) val, evinfo);
        } else if (!(val instanceof Available)) {
            VAlarmUtil.processComponentAlarms(cb, val, ev, currentPrincipal, chg);
            if (val instanceof VPoll) {
                processVvoters((VPoll) val, evinfo, cb, chg, mergeAttendees);
                processCandidates((VPoll) val, evinfo, chg);
            }
        }
        /* Fix up timestamps. */
        if (ev.getCreated() == null) {
            if (ev.getLastmod() != null) {
                ev.setCreated(ev.getLastmod());
                chg.changed(PropertyInfoIndex.CREATED, null, ev.getCreated());
            } else {
                ev.updateDtstamp();
                chg.changed(PropertyInfoIndex.CREATED, null, ev.getCreated());
                chg.changed(PropertyInfoIndex.LAST_MODIFIED, null, ev.getLastmod());
            }
        }
        if (ev.getLastmod() == null) {
            // created cannot be null now
            ev.setLastmod(ev.getCreated());
            chg.changed(PropertyInfoIndex.LAST_MODIFIED, null, ev.getLastmod());
        }
        processTimezones(ev, ical, chg);
        /* Remove any recipients and originator
       */
        if (ev.getRecipients() != null) {
            ev.getRecipients().clear();
        }
        ev.setOriginator(null);
        if (hasXparams.value) {
            /* Save a text copy of the entire event as an x-property */
            Component valCopy = val.copy();
            /* Remove potentially large values */
            prop = valCopy.getProperty(Property.DESCRIPTION);
            if (prop != null) {
                prop.setValue(null);
            }
            prop = valCopy.getProperty(Property.ATTACH);
            // Don't store the entire attachment - we just need the parameters.
            if (prop != null) {
                Value v = (Value) prop.getParameter(Parameter.VALUE);
                if (v != null) {
                    prop.setValue(String.valueOf(prop.getValue().hashCode()));
                }
            }
            chg.addValue(PropertyInfoIndex.XPROP, new BwXproperty(BwXproperty.bedeworkIcal, null, valCopy.toString()));
        }
        chg.processChanges(ev, true);
        ev.setRecurring(new Boolean(ev.isRecurringEntity()));
        if (debug) {
            debugMsg(chg.toString());
            debugMsg(ev.toString());
        }
        if (masterEI != null) {
            // Just return null as this event is on its override list
            return null;
        }
        return evinfo;
    } catch (CalFacadeException cfe) {
        if (debug) {
            cfe.printStackTrace();
        }
        throw cfe;
    } catch (Throwable t) {
        if (debug) {
            t.printStackTrace();
        }
        throw new CalFacadeException(t);
    }
}
Also used : EventInfo(org.bedework.calfacade.svc.EventInfo) FreeBusy(net.fortuna.ical4j.model.property.FreeBusy) VFreeBusy(net.fortuna.ical4j.model.component.VFreeBusy) BwRelatedTo(org.bedework.calfacade.BwRelatedTo) BwRequestStatus(org.bedework.calfacade.BwRequestStatus) DateProperty(net.fortuna.ical4j.model.property.DateProperty) BwCategory(org.bedework.calfacade.BwCategory) BwString(org.bedework.calfacade.BwString) VAvailability(net.fortuna.ical4j.model.component.VAvailability) TextList(net.fortuna.ical4j.model.TextList) AcceptResponse(net.fortuna.ical4j.model.property.AcceptResponse) Available(net.fortuna.ical4j.model.component.Available) RelatedTo(net.fortuna.ical4j.model.property.RelatedTo) BwRelatedTo(org.bedework.calfacade.BwRelatedTo) VEvent(net.fortuna.ical4j.model.component.VEvent) BwFreeBusyComponent(org.bedework.calfacade.BwFreeBusyComponent) BwLocation(org.bedework.calfacade.BwLocation) Categories(net.fortuna.ical4j.model.property.Categories) PeriodList(net.fortuna.ical4j.model.PeriodList) Period(net.fortuna.ical4j.model.Period) Duration(net.fortuna.ical4j.model.property.Duration) BwString(org.bedework.calfacade.BwString) BwContact(org.bedework.calfacade.BwContact) Sequence(net.fortuna.ical4j.model.property.Sequence) Geo(net.fortuna.ical4j.model.property.Geo) BwGeo(org.bedework.calfacade.BwGeo) BwPrincipal(org.bedework.calfacade.BwPrincipal) PropertyInfoIndex(org.bedework.util.calendar.PropertyIndex.PropertyInfoIndex) BwXproperty(org.bedework.calfacade.BwXproperty) Value(net.fortuna.ical4j.model.parameter.Value) Resources(net.fortuna.ical4j.model.property.Resources) BwAttendee(org.bedework.calfacade.BwAttendee) VToDo(net.fortuna.ical4j.model.component.VToDo) VJournal(net.fortuna.ical4j.model.component.VJournal) BwDateTime(org.bedework.calfacade.BwDateTime) DateListProperty(net.fortuna.ical4j.model.property.DateListProperty) BwGeo(org.bedework.calfacade.BwGeo) BwEvent(org.bedework.calfacade.BwEvent) VPoll(net.fortuna.ical4j.model.component.VPoll) Due(net.fortuna.ical4j.model.property.Due) Iterator(java.util.Iterator) Component(net.fortuna.ical4j.model.Component) BwFreeBusyComponent(org.bedework.calfacade.BwFreeBusyComponent) DateListProperty(net.fortuna.ical4j.model.property.DateListProperty) XProperty(net.fortuna.ical4j.model.property.XProperty) Property(net.fortuna.ical4j.model.Property) DateProperty(net.fortuna.ical4j.model.property.DateProperty) BwOrganizer(org.bedework.calfacade.BwOrganizer) XProperty(net.fortuna.ical4j.model.property.XProperty) VFreeBusy(net.fortuna.ical4j.model.component.VFreeBusy) Attach(net.fortuna.ical4j.model.property.Attach) Holder(javax.xml.ws.Holder) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) Date(net.fortuna.ical4j.model.Date) BwAttendee(org.bedework.calfacade.BwAttendee) Attendee(net.fortuna.ical4j.model.property.Attendee) PropertyList(net.fortuna.ical4j.model.PropertyList) DtStart(net.fortuna.ical4j.model.property.DtStart) ChangeTable(org.bedework.calfacade.util.ChangeTable) PercentComplete(net.fortuna.ical4j.model.property.PercentComplete) Parameter(net.fortuna.ical4j.model.Parameter) XParameter(net.fortuna.ical4j.model.parameter.XParameter) DtEnd(net.fortuna.ical4j.model.property.DtEnd)

Example 37 with PropertyList

use of net.fortuna.ical4j.model.PropertyList in project bw-calendar-engine by Bedework.

the class RecurUtil method getRange.

/**
 * Returns range of dates for this recurring event possibly bounded by
 * the supplied maximum end date.
 *
 * @param ev        the recurring event
 * @param maxYears  Provide an upper limit
 * @return the range for this event
 * @throws CalFacadeException
 */
@SuppressWarnings("unchecked")
public static RecurRange getRange(final BwEvent ev, final int maxYears) throws CalFacadeException {
    PropertyList evprops = new PropertyList();
    VEventUtil.doRecurring(ev, evprops);
    RecurRange rr = new RecurRange();
    DtStart start = ev.getDtstart().makeDtStart();
    DtEnd end = ev.getDtend().makeDtEnd();
    Duration duration = new Duration(null, ev.getDuration());
    // boolean durSpecified = ev.getEndType() == BwEvent.endTypeDuration;
    rr.rangeStart = start.getDate();
    for (Object o : evprops) {
        if (o instanceof RDate) {
            RDate rd = (RDate) o;
            for (Object o1 : rd.getDates()) {
                Date d = (Date) o1;
                if (d.before(rr.rangeStart)) {
                    rr.rangeStart = d;
                }
            }
        }
    }
    /* Limit date according to system settings
     */
    Dur dur = new Dur(maxYears * 365, 0, 0, 0);
    Date maxRangeEnd = new Date(dur.getTime(rr.rangeStart));
    if (ev.getParent() != null) {
        BwDateTime pend = ev.getParent().getDtend();
        if (pend != null) {
            Date dt = pend.makeDate();
            if (dt.before(maxRangeEnd)) {
                maxRangeEnd = dt;
            }
        }
    }
    rr.rangeEnd = getLatestRecurrenceDate(evprops, start, end, duration, maxRangeEnd);
    if ((rr.rangeEnd == null) || (rr.rangeEnd.after(maxRangeEnd))) {
        rr.rangeEnd = maxRangeEnd;
    }
    return rr;
}
Also used : Dur(net.fortuna.ical4j.model.Dur) PropertyList(net.fortuna.ical4j.model.PropertyList) DtStart(net.fortuna.ical4j.model.property.DtStart) RDate(net.fortuna.ical4j.model.property.RDate) BwDateTime(org.bedework.calfacade.BwDateTime) Duration(net.fortuna.ical4j.model.property.Duration) BwDuration(org.bedework.calfacade.BwDuration) RDate(net.fortuna.ical4j.model.property.RDate) Date(net.fortuna.ical4j.model.Date) DtEnd(net.fortuna.ical4j.model.property.DtEnd)

Example 38 with PropertyList

use of net.fortuna.ical4j.model.PropertyList in project bw-calendar-engine by Bedework.

the class RecurUtil method getPeriods.

/**
 * Returns a list of instances for this recurring event possibly bounded by
 * the supplied maximum end date.
 *
 * <p>This is mostly a copy of VEvent.getConsumedTime()
 *
 * @param ev        the recurring event
 * @param maxYears  Provide an upper limit
 * @param maxInstances to limit
 * @param startRange null or set earliest
 * @param endRange null or set latest
 * @return a list of periods for this event
 * @throws CalFacadeException on error
 */
public static RecurPeriods getPeriods(final BwEvent ev, final int maxYears, final int maxInstances, final String startRange, final String endRange) throws CalFacadeException {
    final PropertyList evprops = new PropertyList();
    VEventUtil.doRecurring(ev, evprops);
    final RecurPeriods rp = new RecurPeriods();
    // DtStart vstart = (DtStart)IcalUtil.getProperty(comp, Property.DTSTART);
    /* BwDateTime evstart = ev.getDtstart();
    String tzid = evstart.getTzid();

    DtStart start = new DtStart();

    if (tzid != null) {
      start.setTimeZone(timezones.getTimeZone(tzid));
    }

    try {
      start.setValue(evstart.getDtval());
    } catch (Throwable t) {
      throw new CalFacadeException(t);
    }*/
    final DtStart start = ev.getDtstart().makeDtStart();
    if (startRange != null) {
        try {
            rp.rangeStart = new DateTime(startRange);
        } catch (final Throwable t) {
            throw new CalFacadeException(t);
        }
    } else {
        // boolean durSpecified = ev.getEndType() == BwEvent.endTypeDuration;
        rp.rangeStart = start.getDate();
        for (final Object o : evprops) {
            if (o instanceof RDate) {
                final RDate rd = (RDate) o;
                for (final Object o1 : rd.getDates()) {
                    final Date d = (Date) o1;
                    if (d.before(rp.rangeStart)) {
                        rp.rangeStart = d;
                    }
                }
            }
        }
    }
    /* Limit date according to system settings
     */
    final Dur dur = new Dur(maxYears * 365, 0, 0, 0);
    Date maxRangeEnd = new Date(dur.getTime(rp.rangeStart));
    if (ev.getParent() != null) {
        final BwDateTime pend = ev.getParent().getDtend();
        if (pend != null) {
            final Date dt = pend.makeDate();
            if (dt.before(maxRangeEnd)) {
                maxRangeEnd = dt;
            }
        }
    }
    final DtEnd end = ev.getDtend().makeDtEnd();
    if (endRange != null) {
        try {
            rp.rangeEnd = new DateTime(endRange);
        } catch (final Throwable t) {
            throw new CalFacadeException(t);
        }
    } else {
        final Duration duration = new Duration(null, ev.getDuration());
        rp.rangeEnd = getLatestRecurrenceDate(evprops, start, end, duration, maxRangeEnd);
        if ((rp.rangeEnd == null) || (rp.rangeEnd.after(maxRangeEnd))) {
            rp.rangeEnd = maxRangeEnd;
        }
    }
    Period rangePeriod = new Period(new DateTime(rp.rangeStart), new DateTime(rp.rangeEnd));
    VEvent vev = new VEvent();
    PropertyList vevprops = vev.getProperties();
    vevprops.addAll(evprops);
    if (!ev.getSuppressed()) {
        // Allow inclusion of master start/end
        vevprops.add(start);
        vevprops.add(end);
    } else {
        // Move start/end outside of our period
        Dur evdur = new Dur(ev.getDuration());
        // Ensure at least a day
        Dur setback = evdur.add(new Dur(1, 0, 0, 0));
        boolean dateOnly = ev.getDtstart().getDateType();
        Date adjustedEnd;
        if (dateOnly) {
            adjustedEnd = new Date(rp.rangeStart);
        } else {
            adjustedEnd = new DateTime(rp.rangeStart);
        }
        adjustedEnd.setTime(setback.negate().getTime(rp.rangeStart).getTime());
        vevprops.add(new DtEnd(adjustedEnd));
        // End now before range - make start evdur before that
        Date adjustedStart;
        if (dateOnly) {
            adjustedStart = new Date(adjustedEnd);
        } else {
            adjustedStart = new DateTime(adjustedEnd);
        }
        adjustedStart.setTime(evdur.negate().getTime(adjustedEnd).getTime());
        vevprops.add(new DtStart(adjustedStart));
    }
    PeriodList pl = vev.calculateRecurrenceSet(rangePeriod);
    /*
    PeriodList periods = new PeriodList();
    if (ev.getDtstart().isUTC()) {
      periods.setUtc(true);
    } else if (start.getDate() instanceof DateTime) {
      periods.setTimeZone(((DateTime)start.getDate()).getTimeZone());
    } else {
      try {
        periods.setTimeZone(Timezones.getDefaultTz());
      } catch (Throwable t) {
        throw new CalFacadeException(t);
      }
    }
    rp.instances = periods;

    // if no start date return empty list..
    if (start == null) {
      return rp;
    }
    // if an explicit event duration is not specified, derive a value for recurring
    // periods from the end date..
    Dur rDuration;
    Dur adjustDuration;
    if (duration == null) {
      if (end == null) {
        rDuration = new Dur(0);
        adjustDuration = new Dur(0, 0, 0, 1); // 1 second fudge
      } else {
        rDuration = new Dur(start.getDate(), end.getDate());
        adjustDuration = rDuration;
      }
    } else {
      rDuration = duration.getDuration();
      adjustDuration = rDuration;
    }
    // adjust range start back by duration to allow for recurrences that
    // start before the range but finish inside..
//  FIXME: See bug #1325558..
    Date adjustedRangeStart = new DateTime(rp.rangeStart);
    adjustedRangeStart.setTime(adjustDuration.negate().getTime(rp.rangeStart).getTime());

    // recurrence dates..
    PropertyList rDates = evprops.getProperties(Property.RDATE);
    for (Iterator i = rDates.iterator(); i.hasNext();) {
      RDate rdate = (RDate) i.next();

      if (Value.PERIOD.equals(rdate.getParameter(Parameter.VALUE))) {
        /* These fully define the period * /
        for (Iterator j = rdate.getPeriods().iterator(); j.hasNext();) {
          Period period = (Period) j.next();
          if (period.getStart().before(rp.rangeEnd) &&
              period.getEnd().after(rp.rangeStart)) {
            periods.add(period);
          }
        }
      } else {
        // Create a period based on rdate and duration
        DateList startDates = rdate.getDates();
        for (int j = 0; j < startDates.size(); j++) {
          Date startDate = (Date) startDates.get(j);
          periods.add(new Period(new DateTime(startDate), rDuration));
        }
      }
    }

    Value startVal = (Value)start.getParameter(Parameter.VALUE);
    if (startVal == null) {
      startVal = Value.DATE_TIME;
    }

    // recurrence rules..
    PropertyList rRules = evprops.getProperties(Property.RRULE);
    for (Iterator i = rRules.iterator(); i.hasNext();) {
      RRule rrule = (RRule) i.next();
      Recur recur = rrule.getRecur();

      // Limit nummber of instances.

      DateList startDates = recur.getDates(start.getDate(),
                                           adjustedRangeStart,
                                           rp.rangeEnd,
                                           startVal,
                                           maxInstances);
//    DateList startDates = rrule.getRecur().getDates(start.getDate(), rangeStart, rangeEnd, (Value) start.getParameters().getParameter(Parameter.VALUE));
      for (int j = 0; j < startDates.size(); j++) {
        Date startDate = (Date) startDates.get(j);
        periods.add(new Period(new DateTime(startDate), rDuration));
      }
    }

    // add initial instance if intersection with the specified period.

    if (!ev.getSuppressed()) {
      Period startPeriod = null;
      if (!durSpecified) {
        startPeriod = new Period(new DateTime(start.getDate()),
                                 new DateTime(end.getDate()));
      } else {
        startPeriod = new Period(new DateTime(start.getDate()),
                                 duration.getDuration());
      }
      if (rangePeriod.intersects(startPeriod)) {
          periods.add(startPeriod);
      }
    }

    // exception dates..
    PropertyList exDates = evprops.getProperties(Property.EXDATE);
    for (Iterator i = exDates.iterator(); i.hasNext();) {
      ExDate exDate = (ExDate) i.next();
      for (Iterator j = periods.iterator(); j.hasNext();) {
        Period period = (Period) j.next();
        DateList dl = exDate.getDates();
        // for DATE-TIME instances check for DATE-based exclusions also..
        if (dl.contains(period.getStart())) {
          j.remove();
        } else if (dl.contains(new Date(period.getStart()))) {
          j.remove();
        }
      }
    }
    // exception rules..
    // FIXME: exception rules should be consistent with exception dates (i.e. not use periods?)..
    PropertyList exRules = evprops.getProperties(Property.EXRULE);
    PeriodList exPeriods = new PeriodList();
    for (Iterator i = exRules.iterator(); i.hasNext();) {
      ExRule exrule = (ExRule) i.next();
//    DateList startDates = exrule.getRecur().getDates(start.getDate(), adjustedRangeStart, rangeEnd, (Value) start.getParameters().getParameter(Parameter.VALUE));
      DateList startDates = exrule.getRecur().getDates(start.getDate(),
                                                       rp.rangeStart,
                                                       rp.rangeEnd,
                                                       startVal);
      for (Iterator j = startDates.iterator(); j.hasNext();) {
        Date startDate = (Date) j.next();
        exPeriods.add(new Period(new DateTime(startDate), rDuration));
      }
    }
    // apply exceptions..
    if (!exPeriods.isEmpty()) {
      periods = periods.subtract(exPeriods);
    }
    // if periods already specified through recurrence, return..
    // ..also normalise before returning.
//    if (!periods.isEmpty()) {
//      periods = periods.normalise();
//    }
 *
 */
    if (pl.size() <= maxInstances) {
        rp.instances = pl;
    } else {
        rp.instances = new TreeSet<Period>();
        for (Object o : pl) {
            rp.instances.add((Period) o);
            if (rp.instances.size() == maxInstances) {
                break;
            }
        }
    }
    return rp;
}
Also used : Dur(net.fortuna.ical4j.model.Dur) VEvent(net.fortuna.ical4j.model.component.VEvent) RDate(net.fortuna.ical4j.model.property.RDate) BwDateTime(org.bedework.calfacade.BwDateTime) Period(net.fortuna.ical4j.model.Period) PeriodList(net.fortuna.ical4j.model.PeriodList) Duration(net.fortuna.ical4j.model.property.Duration) BwDuration(org.bedework.calfacade.BwDuration) DateTime(net.fortuna.ical4j.model.DateTime) BwDateTime(org.bedework.calfacade.BwDateTime) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) RDate(net.fortuna.ical4j.model.property.RDate) Date(net.fortuna.ical4j.model.Date) PropertyList(net.fortuna.ical4j.model.PropertyList) DtStart(net.fortuna.ical4j.model.property.DtStart) DtEnd(net.fortuna.ical4j.model.property.DtEnd)

Example 39 with PropertyList

use of net.fortuna.ical4j.model.PropertyList in project bw-calendar-engine by Bedework.

the class VFreeUtil method toVFreeBusy.

/**
 * Make a VFreeBusy object from a BwFreeBusy.
 */
/**
 * @param val
 * @return VFreeBusy
 * @throws CalFacadeException
 */
public static VFreeBusy toVFreeBusy(final BwEvent val) throws CalFacadeException {
    try {
        VFreeBusy vfb = new VFreeBusy(IcalUtil.makeDateTime(val.getDtstart()), IcalUtil.makeDateTime(val.getDtend()));
        PropertyList pl = vfb.getProperties();
        Property prop;
        /* ------------------- Attendees -------------------- */
        if (val.getNumAttendees() > 0) {
            for (BwAttendee att : val.getAttendees()) {
                pl.add(setAttendee(att));
            }
        }
        if (val.getNumComments() > 0) {
            for (BwString str : val.getComments()) {
                // LANG
                pl.add(new Comment(str.getValue()));
            }
        }
        if (val.getDtstamp() != null) {
            DtStamp dts = (DtStamp) pl.getProperty(Property.DTSTAMP);
            if (dts == null) {
                prop = new DtStamp(new DateTime(val.getDtstamp()));
                // if (pars.includeDateTimeProperty) {
                // prop.getParameters().add(Value.DATE_TIME);
                // }
                pl.add(prop);
            } else {
                dts.setDateTime(new DateTime(val.getDtstamp()));
            }
        }
        /* ------------------- freebusy -------------------- */
        Collection<BwFreeBusyComponent> times = val.getFreeBusyPeriods();
        if (times != null) {
            for (BwFreeBusyComponent fbc : times) {
                FreeBusy fb = new FreeBusy();
                int type = fbc.getType();
                if (type == BwFreeBusyComponent.typeBusy) {
                    addParameter(fb, FbType.BUSY);
                } else if (type == BwFreeBusyComponent.typeFree) {
                    addParameter(fb, FbType.FREE);
                } else if (type == BwFreeBusyComponent.typeBusyUnavailable) {
                    addParameter(fb, FbType.BUSY_UNAVAILABLE);
                } else if (type == BwFreeBusyComponent.typeBusyTentative) {
                    addParameter(fb, FbType.BUSY_TENTATIVE);
                } else {
                    throw new CalFacadeException("Bad free-busy type " + type);
                }
                PeriodList pdl = fb.getPeriods();
                for (Period p : fbc.getPeriods()) {
                    // XXX inverse.ca plugin cannot handle durations.
                    Period np = new Period(p.getStart(), p.getEnd());
                    pdl.add(np);
                }
                pl.add(fb);
            }
        }
        /* ------------------- Organizer -------------------- */
        BwOrganizer org = val.getOrganizer();
        if (org != null) {
            pl.add(setOrganizer(org));
        }
        if (val.getUid() != null) {
            pl.add(new Uid(val.getUid()));
        }
        return vfb;
    } catch (CalFacadeException cfe) {
        throw cfe;
    } catch (Throwable t) {
        throw new CalFacadeException(t);
    }
}
Also used : Comment(net.fortuna.ical4j.model.property.Comment) BwFreeBusyComponent(org.bedework.calfacade.BwFreeBusyComponent) VFreeBusy(net.fortuna.ical4j.model.component.VFreeBusy) FreeBusy(net.fortuna.ical4j.model.property.FreeBusy) VFreeBusy(net.fortuna.ical4j.model.component.VFreeBusy) PeriodList(net.fortuna.ical4j.model.PeriodList) Period(net.fortuna.ical4j.model.Period) BwString(org.bedework.calfacade.BwString) DateTime(net.fortuna.ical4j.model.DateTime) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) Uid(net.fortuna.ical4j.model.property.Uid) DtStamp(net.fortuna.ical4j.model.property.DtStamp) PropertyList(net.fortuna.ical4j.model.PropertyList) Property(net.fortuna.ical4j.model.Property) BwAttendee(org.bedework.calfacade.BwAttendee) BwOrganizer(org.bedework.calfacade.BwOrganizer)

Example 40 with PropertyList

use of net.fortuna.ical4j.model.PropertyList in project openolat by klemens.

the class ICalFileCalendarManager method getKalendarEvent.

/**
 * Build a KalendarEvent out of a source VEvent.
 * @param event
 * @return
 */
private KalendarEvent getKalendarEvent(VEvent event) {
    // subject
    Summary eventsummary = event.getSummary();
    String subject = "";
    if (eventsummary != null)
        subject = eventsummary.getValue();
    // start
    DtStart dtStart = event.getStartDate();
    Date start = dtStart.getDate();
    Duration dur = event.getDuration();
    // end
    Date end = null;
    if (dur != null) {
        end = dur.getDuration().getTime(start);
    } else if (event.getEndDate() != null) {
        end = event.getEndDate().getDate();
    }
    // check all day event first
    boolean isAllDay = false;
    Parameter dateParameter = event.getProperties().getProperty(Property.DTSTART).getParameters().getParameter(Value.DATE.getName());
    if (dateParameter != null) {
        isAllDay = true;
        // Make sure the time of the dates are 00:00 localtime because DATE fields in iCal are GMT 00:00
        // Note that start date and end date can have different offset because of daylight saving switch
        java.util.TimeZone timezone = java.util.GregorianCalendar.getInstance().getTimeZone();
        start = new Date(start.getTime() - timezone.getOffset(start.getTime()));
        end = new Date(end.getTime() - timezone.getOffset(end.getTime()));
        // adjust end date: ICal sets end dates to the next day
        end = new Date(end.getTime() - (1000 * 60 * 60 * 24));
    } else if (start != null && end != null && (end.getTime() - start.getTime()) == (24 * 60 * 60 * 1000)) {
        // check that start has no hour, no minute and no second
        java.util.Calendar cal = java.util.Calendar.getInstance();
        cal.setTime(start);
        isAllDay = cal.get(java.util.Calendar.HOUR_OF_DAY) == 0 && cal.get(java.util.Calendar.MINUTE) == 0 && cal.get(java.util.Calendar.SECOND) == 0 && cal.get(java.util.Calendar.MILLISECOND) == 0;
        // adjust end date: ICal sets end dates to the next day
        end = new Date(end.getTime() - (1000 * 60 * 60 * 24));
    }
    Uid eventuid = event.getUid();
    String uid;
    if (eventuid != null) {
        uid = eventuid.getValue();
    } else {
        uid = CodeHelper.getGlobalForeverUniqueID();
    }
    RecurrenceId eventRecurenceId = event.getRecurrenceId();
    String recurrenceId = null;
    if (eventRecurenceId != null) {
        recurrenceId = eventRecurenceId.getValue();
    }
    KalendarEvent calEvent = new KalendarEvent(uid, recurrenceId, subject, start, end);
    calEvent.setAllDayEvent(isAllDay);
    // classification
    Clazz classification = event.getClassification();
    if (classification != null) {
        String sClass = classification.getValue();
        int iClassification = KalendarEvent.CLASS_PRIVATE;
        if (sClass.equals(ICAL_CLASS_PRIVATE.getValue()))
            iClassification = KalendarEvent.CLASS_PRIVATE;
        else if (sClass.equals(ICAL_CLASS_X_FREEBUSY.getValue()))
            iClassification = KalendarEvent.CLASS_X_FREEBUSY;
        else if (sClass.equals(ICAL_CLASS_PUBLIC.getValue()))
            iClassification = KalendarEvent.CLASS_PUBLIC;
        calEvent.setClassification(iClassification);
    }
    // created/last modified
    Created created = event.getCreated();
    if (created != null) {
        calEvent.setCreated(created.getDate().getTime());
    }
    // created/last modified
    Contact contact = (Contact) event.getProperty(Property.CONTACT);
    if (contact != null) {
        calEvent.setCreatedBy(contact.getValue());
    }
    LastModified lastModified = event.getLastModified();
    if (lastModified != null) {
        calEvent.setLastModified(lastModified.getDate().getTime());
    }
    Description description = event.getDescription();
    if (description != null) {
        calEvent.setDescription(description.getValue());
    }
    // location
    Location location = event.getLocation();
    if (location != null) {
        calEvent.setLocation(location.getValue());
    }
    // links if any
    PropertyList linkProperties = event.getProperties(ICAL_X_OLAT_LINK);
    List<KalendarEventLink> kalendarEventLinks = new ArrayList<KalendarEventLink>();
    for (Iterator<?> iter = linkProperties.iterator(); iter.hasNext(); ) {
        XProperty linkProperty = (XProperty) iter.next();
        if (linkProperty != null) {
            String encodedLink = linkProperty.getValue();
            StringTokenizer st = new StringTokenizer(encodedLink, "§", false);
            if (st.countTokens() >= 4) {
                String provider = st.nextToken();
                String id = st.nextToken();
                String displayName = st.nextToken();
                String uri = st.nextToken();
                String iconCss = "";
                // migration: iconCss has been added later, check if available first
                if (st.hasMoreElements()) {
                    iconCss = st.nextToken();
                }
                KalendarEventLink eventLink = new KalendarEventLink(provider, id, displayName, uri, iconCss);
                kalendarEventLinks.add(eventLink);
            }
        }
    }
    calEvent.setKalendarEventLinks(kalendarEventLinks);
    Property comment = event.getProperty(ICAL_X_OLAT_COMMENT);
    if (comment != null)
        calEvent.setComment(comment.getValue());
    Property numParticipants = event.getProperty(ICAL_X_OLAT_NUMPARTICIPANTS);
    if (numParticipants != null)
        calEvent.setNumParticipants(Integer.parseInt(numParticipants.getValue()));
    Property participants = event.getProperty(ICAL_X_OLAT_PARTICIPANTS);
    if (participants != null) {
        StringTokenizer strTok = new StringTokenizer(participants.getValue(), "§", false);
        String[] parts = new String[strTok.countTokens()];
        for (int i = 0; strTok.hasMoreTokens(); i++) {
            parts[i] = strTok.nextToken();
        }
        calEvent.setParticipants(parts);
    }
    Property sourceNodId = event.getProperty(ICAL_X_OLAT_SOURCENODEID);
    if (sourceNodId != null) {
        calEvent.setSourceNodeId(sourceNodId.getValue());
    }
    // managed properties
    Property managed = event.getProperty(ICAL_X_OLAT_MANAGED);
    if (managed != null) {
        String value = managed.getValue();
        if ("true".equals(value)) {
            value = "all";
        }
        CalendarManagedFlag[] values = CalendarManagedFlag.toEnum(value);
        calEvent.setManagedFlags(values);
    }
    Property externalId = event.getProperty(ICAL_X_OLAT_EXTERNAL_ID);
    if (externalId != null) {
        calEvent.setExternalId(externalId.getValue());
    }
    Property externalSource = event.getProperty(ICAL_X_OLAT_EXTERNAL_SOURCE);
    if (externalSource != null) {
        calEvent.setExternalSource(externalSource.getValue());
    }
    // recurrence
    if (event.getProperty(ICAL_RRULE) != null) {
        calEvent.setRecurrenceRule(event.getProperty(ICAL_RRULE).getValue());
    }
    // recurrence exclusions
    if (event.getProperty(ICAL_EXDATE) != null) {
        calEvent.setRecurrenceExc(event.getProperty(ICAL_EXDATE).getValue());
    }
    return calEvent;
}
Also used : Description(net.fortuna.ical4j.model.property.Description) ArrayList(java.util.ArrayList) KalendarEventLink(org.olat.commons.calendar.model.KalendarEventLink) Created(net.fortuna.ical4j.model.property.Created) LastModified(net.fortuna.ical4j.model.property.LastModified) CalendarManagedFlag(org.olat.commons.calendar.CalendarManagedFlag) Clazz(net.fortuna.ical4j.model.property.Clazz) XProperty(net.fortuna.ical4j.model.property.XProperty) Property(net.fortuna.ical4j.model.Property) XProperty(net.fortuna.ical4j.model.property.XProperty) Calendar(net.fortuna.ical4j.model.Calendar) KalendarEvent(org.olat.commons.calendar.model.KalendarEvent) Duration(net.fortuna.ical4j.model.property.Duration) Date(java.util.Date) ExDate(net.fortuna.ical4j.model.property.ExDate) Contact(net.fortuna.ical4j.model.property.Contact) Uid(net.fortuna.ical4j.model.property.Uid) StringTokenizer(java.util.StringTokenizer) DtStart(net.fortuna.ical4j.model.property.DtStart) PropertyList(net.fortuna.ical4j.model.PropertyList) Summary(net.fortuna.ical4j.model.property.Summary) Parameter(net.fortuna.ical4j.model.Parameter) RecurrenceId(net.fortuna.ical4j.model.property.RecurrenceId) Location(net.fortuna.ical4j.model.property.Location)

Aggregations

PropertyList (net.fortuna.ical4j.model.PropertyList)41 VEvent (net.fortuna.ical4j.model.component.VEvent)17 Property (net.fortuna.ical4j.model.Property)13 XProperty (net.fortuna.ical4j.model.property.XProperty)12 DateTime (net.fortuna.ical4j.model.DateTime)11 CalFacadeException (org.bedework.calfacade.exc.CalFacadeException)11 DtStart (net.fortuna.ical4j.model.property.DtStart)9 Uid (net.fortuna.ical4j.model.property.Uid)9 URISyntaxException (java.net.URISyntaxException)8 Calendar (net.fortuna.ical4j.model.Calendar)8 Description (net.fortuna.ical4j.model.property.Description)8 Date (java.util.Date)7 Period (net.fortuna.ical4j.model.Period)7 DtEnd (net.fortuna.ical4j.model.property.DtEnd)7 Duration (net.fortuna.ical4j.model.property.Duration)7 RecurrenceId (net.fortuna.ical4j.model.property.RecurrenceId)7 Parameter (net.fortuna.ical4j.model.Parameter)6 PeriodList (net.fortuna.ical4j.model.PeriodList)6 VFreeBusy (net.fortuna.ical4j.model.component.VFreeBusy)6 VTimeZone (net.fortuna.ical4j.model.component.VTimeZone)6