Search in sources :

Example 1 with ChangeTableEntry

use of org.bedework.calfacade.util.ChangeTableEntry in project bw-calendar-engine by Bedework.

the class Events method setScheduleState.

/* Flag this as an attendee scheduling object or an organizer scheduling object
   */
private void setScheduleState(final BwEvent ev, final boolean adding, final boolean schedulingInbox) throws CalFacadeException {
    ev.setOrganizerSchedulingObject(false);
    ev.setAttendeeSchedulingObject(false);
    if ((ev.getEntityType() != IcalDefs.entityTypeEvent) && (ev.getEntityType() != IcalDefs.entityTypeTodo) && (ev.getEntityType() != IcalDefs.entityTypeVpoll)) {
        // Not a possible scheduling entity
        return;
    }
    final BwOrganizer org = ev.getOrganizer();
    final Set<BwAttendee> atts = ev.getAttendees();
    if (Util.isEmpty(atts) || (org == null)) {
        return;
    }
    final String curPrincipal = getSvc().getPrincipal().getPrincipalRef();
    final Directories dirs = getSvc().getDirectories();
    AccessPrincipal evPrincipal = dirs.caladdrToPrincipal(org.getOrganizerUri());
    if ((evPrincipal != null) && (evPrincipal.getPrincipalRef().equals(curPrincipal))) {
        ev.setOrganizerSchedulingObject(true);
        /* If we are expanding groups do so here */
        final ChangeTable chg = ev.getChangeset(getPrincipalHref());
        final Set<BwAttendee> groups = new TreeSet<>();
        if (!schedulingInbox) {
            final ChangeTableEntry cte = chg.getEntry(PropertyInfoIndex.ATTENDEE);
            checkAttendees: for (final BwAttendee att : atts) {
                if (CuType.GROUP.getValue().equals(att.getCuType())) {
                    groups.add(att);
                }
                final AccessPrincipal attPrincipal = getSvc().getDirectories().caladdrToPrincipal(att.getAttendeeUri());
                if ((attPrincipal != null) && (attPrincipal.getPrincipalRef().equals(curPrincipal))) {
                    // It's us
                    continue;
                }
                if (att.getPartstat().equals(IcalDefs.partstatValNeedsAction)) {
                    continue;
                }
                if (adding) {
                    // Can't add an event with attendees set to accepted
                    att.setPartstat(IcalDefs.partstatValNeedsAction);
                    continue;
                }
                // Not adding event. Did we add attendee?
                if ((cte != null) && !Util.isEmpty(cte.getAddedValues())) {
                    for (final Object o : cte.getAddedValues()) {
                        final BwAttendee chgAtt = (BwAttendee) o;
                        if (chgAtt.getCn().equals(att.getCn())) {
                            att.setPartstat(IcalDefs.partstatValNeedsAction);
                            continue checkAttendees;
                        }
                    }
                }
            }
        }
        try {
            /* If this is a vpoll we need the vvoters as we are going to
           have to remove the group vvoter entry and clone it for the
           attendees we add.

           I think this will work for any poll mode - if not we may
           have to rethink this approach.
         */
            Map<String, VVoter> voters = null;
            final boolean vpoll;
            if (ev.getEntityType() == IcalDefs.entityTypeVpoll) {
                voters = IcalUtil.parseVpollVvoters(ev);
                // We'll add them all back
                ev.clearVvoters();
                vpoll = true;
            } else {
                vpoll = false;
            }
            for (final BwAttendee att : groups) {
                /* If the group is in one of our domains we can try to expand it.
           * We should leave it if it's an external id.
           */
                final Holder<Boolean> trunc = new Holder<>();
                final List<BwPrincipalInfo> groupPis = dirs.find(att.getAttendeeUri(), att.getCuType(), // expand
                true, trunc);
                if ((groupPis == null) || (groupPis.size() != 1)) {
                    continue;
                }
                final BwPrincipalInfo pi = groupPis.get(0);
                if (pi.getMembers() == null) {
                    continue;
                }
                VVoter groupVvoter = null;
                Voter groupVoter = null;
                PropertyList pl = null;
                if (vpoll) {
                    groupVvoter = voters.get(att.getAttendeeUri());
                    if (groupVvoter == null) {
                        if (debug) {
                            warn("No vvoter found for " + att.getAttendeeUri());
                        }
                        continue;
                    }
                    voters.remove(att.getAttendeeUri());
                    groupVoter = groupVvoter.getVoter();
                    pl = groupVvoter.getProperties();
                }
                // Remove the group
                ev.removeAttendee(att);
                chg.changed(PropertyInfoIndex.ATTENDEE, att, null);
                for (final BwPrincipalInfo mbrPi : pi.getMembers()) {
                    if (mbrPi.getCaladruri() == null) {
                        continue;
                    }
                    final BwAttendee mbrAtt = new BwAttendee();
                    mbrAtt.setType(att.getType());
                    mbrAtt.setAttendeeUri(mbrPi.getCaladruri());
                    mbrAtt.setCn(mbrPi.getEmail());
                    mbrAtt.setCuType(mbrPi.getKind());
                    mbrAtt.setMember(att.getAttendeeUri());
                    ev.addAttendee(mbrAtt);
                    chg.addValue(PropertyInfoIndex.ATTENDEE, mbrAtt);
                    if (vpoll) {
                        pl.remove(groupVoter);
                        groupVoter = IcalUtil.setVoter(mbrAtt);
                        pl.add(groupVoter);
                        ev.addVvoter(groupVvoter.toString());
                    }
                }
            }
            if (vpoll) {
                // Add back any remaining vvoters
                for (VVoter vv : voters.values()) {
                    ev.addVvoter(vv.toString());
                }
            }
        } catch (final CalFacadeException cfe) {
            throw cfe;
        } catch (final Throwable t) {
            throw new CalFacadeException(t);
        }
        if (ev instanceof BwEventProxy) {
            // Only add x-property to master
            return;
        }
        if (CalFacadeDefs.jasigSchedulingAssistant.equals(getPars().getClientId())) {
            ev.addXproperty(new BwXproperty(BwXproperty.bedeworkSchedAssist, null, "true"));
        }
        return;
    }
    for (final BwAttendee att : atts) {
        /* See if at least one attendee is us */
        evPrincipal = getSvc().getDirectories().caladdrToPrincipal(att.getAttendeeUri());
        if ((evPrincipal != null) && (evPrincipal.getPrincipalRef().equals(curPrincipal))) {
            ev.setAttendeeSchedulingObject(true);
            break;
        }
    }
}
Also used : VVoter(net.fortuna.ical4j.model.component.VVoter) Holder(javax.xml.ws.Holder) BwEventProxy(org.bedework.calfacade.BwEventProxy) AccessPrincipal(org.bedework.access.AccessPrincipal) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) Directories(org.bedework.calfacade.ifs.Directories) PropertyList(net.fortuna.ical4j.model.PropertyList) BwXproperty(org.bedework.calfacade.BwXproperty) ChangeTable(org.bedework.calfacade.util.ChangeTable) TreeSet(java.util.TreeSet) Voter(net.fortuna.ical4j.model.property.Voter) VVoter(net.fortuna.ical4j.model.component.VVoter) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry) BwAttendee(org.bedework.calfacade.BwAttendee) BwPrincipalInfo(org.bedework.calfacade.BwPrincipalInfo) BwOrganizer(org.bedework.calfacade.BwOrganizer)

Example 2 with ChangeTableEntry

use of org.bedework.calfacade.util.ChangeTableEntry in project bw-calendar-engine by Bedework.

the class Events method setEntityCategories.

@Override
public SetEntityCategoriesResult setEntityCategories(final CategorisedEntity ent, final Set<BwCategory> extraCats, final Set<String> defCatUids, final Set<String> allDefCatUids, final Collection<String> strCatUids, final ChangeTable changes) throws CalFacadeException {
    // XXX We should use the change table code for this.
    final SetEntityCategoriesResult secr = new SetEntityCategoriesResult();
    /* categories already set in event */
    final Set<BwCategory> entcats = ent.getCategories();
    final Map<String, BwCategory> entcatMap = new HashMap<>();
    if (!Util.isEmpty(entcats)) {
        for (final BwCategory entcat : entcats) {
            entcatMap.put(entcat.getUid(), entcat);
        }
    }
    if (Util.isEmpty(strCatUids) && Util.isEmpty(extraCats) && Util.isEmpty(defCatUids) && Util.isEmpty(allDefCatUids)) {
        if (!Util.isEmpty(entcats)) {
            if (changes != null) {
                final ChangeTableEntry cte = changes.getEntry(PropertyInfoIndex.CATEGORIES);
                cte.setRemovedValues(new ArrayList<>(entcats));
            }
            secr.numRemoved = entcats.size();
            entcats.clear();
        }
        secr.rcode = success;
        return secr;
    }
    final Set<BwCategory> cats = new TreeSet<>();
    if (extraCats != null) {
        cats.addAll(extraCats);
    }
    if (!Util.isEmpty(defCatUids)) {
        for (final String uid : defCatUids) {
            final BwCategory cat = getSvc().getCategoriesHandler().getPersistent(uid);
            if (cat != null) {
                cats.add(cat);
            }
        }
    }
    if (!Util.isEmpty(allDefCatUids) && (entcats != null)) {
        for (final String catUid : allDefCatUids) {
            /* If it's in the event add it to the list we're building then move on
         * to the next requested category.
         */
            final BwCategory entcat = entcatMap.get(catUid);
            if (entcat != null) {
                cats.add(entcat);
            }
        }
    }
    if (!Util.isEmpty(strCatUids)) {
        buildList: for (final String catUid : strCatUids) {
            /* If it's in the event add it to the list we're building then move on
         * to the next requested category.
         */
            final BwCategory entcat = entcatMap.get(catUid);
            if (entcat != null) {
                cats.add(entcat);
                continue buildList;
            }
            final BwCategory cat = getSvc().getCategoriesHandler().getPersistent(catUid);
            if (cat != null) {
                cats.add(cat);
            }
        }
    }
    /* cats now contains category objects corresponding to the parameters
     *
     * Now we need to add or remove any in the event but not in our list.
     */
    /* First make a list to remove - to avoid concurrent update
     * problems with the iterator
     */
    final ArrayList<BwCategory> toRemove = new ArrayList<>();
    if (entcats != null) {
        for (final BwCategory evcat : entcats) {
            if (cats.contains(evcat)) {
                cats.remove(evcat);
                continue;
            }
            toRemove.add(evcat);
        }
    }
    for (final BwCategory cat : cats) {
        ent.addCategory(cat);
        secr.numAdded++;
    }
    for (final BwCategory cat : toRemove) {
        if (entcats.remove(cat)) {
            secr.numRemoved++;
        }
    }
    if ((changes != null) && (secr.numAdded > 0) && (secr.numRemoved > 0)) {
        final ChangeTableEntry cte = changes.getEntry(PropertyInfoIndex.CATEGORIES);
        cte.setRemovedValues(toRemove);
        cte.setAddedValues(cats);
    }
    secr.rcode = success;
    return secr;
}
Also used : HashMap(java.util.HashMap) TreeSet(java.util.TreeSet) BwCategory(org.bedework.calfacade.BwCategory) ArrayList(java.util.ArrayList) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry)

Example 3 with ChangeTableEntry

use of org.bedework.calfacade.util.ChangeTableEntry in project bw-calendar-engine by Bedework.

the class DtStartPropUpdater method applyUpdate.

@Override
public UpdateResult applyUpdate(final UpdateInfo ui) throws WebdavException {
    try {
        BwEvent ev = ui.getEvent();
        boolean scheduleReply = ev.getScheduleMethod() == ScheduleMethods.methodTypeReply;
        // No dates valid for reply
        DtstartPropType dt = (DtstartPropType) ui.getProp();
        DatesState ds = (DatesState) ui.getState(DatesState.stateName);
        if (ds == null) {
            ds = new DatesState(ev);
            ui.saveState(DatesState.stateName, ds);
        }
        ChangeTableEntry cte = ui.getCte();
        if (ui.isRemove()) {
            if (!scheduleReply && (ev.getEntityType() != IcalDefs.entityTypeTodo)) {
                return new UpdateResult("Entity requires start date");
            }
            cte.setDeleted(ev.getDtstart());
            ds.start = null;
            return UpdateResult.getOkResult();
        }
        if (ui.isAdd()) {
            if (!ev.getNoStart()) {
                return new UpdateResult("Entity already has start date - cannot add");
            }
            ds.start = BwDateTime.makeBwDateTime(dt);
            cte.setAdded(ds.start);
            return UpdateResult.getOkResult();
        }
        /* Changing dtstart - either value or parameters */
        if (ev.getNoStart()) {
            return new UpdateResult("Entity has no start date - cannot change");
        }
        Holder<BwDateTime> resdt = new Holder<BwDateTime>();
        UpdateResult ur = makeDt(ev.getDtstart(), resdt, ui);
        if (!ur.getOk()) {
            return ur;
        }
        if (resdt.value != null) {
            cte.setChanged(ev.getDtstart(), resdt.value);
            ds.start = resdt.value;
        }
        return UpdateResult.getOkResult();
    } catch (CalFacadeException cfe) {
        throw new WebdavException(cfe);
    }
}
Also used : BwDateTime(org.bedework.calfacade.BwDateTime) Holder(javax.xml.ws.Holder) WebdavException(org.bedework.webdav.servlet.shared.WebdavException) BwEvent(org.bedework.calfacade.BwEvent) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry) DtstartPropType(ietf.params.xml.ns.icalendar_2.DtstartPropType) UpdateResult(org.bedework.caldav.server.sysinterface.SysIntf.UpdateResult) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException)

Example 4 with ChangeTableEntry

use of org.bedework.calfacade.util.ChangeTableEntry in project bw-calendar-engine by Bedework.

the class ExdatePropUpdater method applyUpdate.

public UpdateResult applyUpdate(final UpdateInfo ui) throws WebdavException {
    try {
        BwEvent ev = ui.getEvent();
        ChangeTableEntry cte = ui.getCte();
        Set<BwDateTime> evDts = ev.getExdates();
        DateDatetimePropertyType dt = (DateDatetimePropertyType) ui.getProp();
        String dtUTC = XcalUtil.getUTC(dt, ui.getTzs());
        if (ui.isRemove()) {
            removeDt(dtUTC, evDts, cte);
            return UpdateResult.getOkResult();
        }
        BwDateTime prdt = BwDateTime.makeBwDateTime(dt);
        if (ui.isAdd()) {
            addDt(prdt, evDts, cte);
            return UpdateResult.getOkResult();
        }
        /* Changing exdate maybe just changing the parameters (UTC unchanged) or
       * an actual value change. Second case is really a remove and add
       */
        BwDateTime newdt = BwDateTime.makeBwDateTime((DateDatetimePropertyType) ui.getUpdprop());
        if (prdt.getDate().equals(newdt.getDate())) {
            // tzid or date only?
            if (prdt.getTzid().equals(newdt.getTzid()) && (prdt.getDateType() == newdt.getDateType())) {
                // Unchanged
                return UpdateResult.getOkResult();
            } else {
                evDts.remove(prdt);
                evDts.add(newdt);
                cte.addChangedValue(newdt);
            }
        }
        /* Do remove then add */
        removeDt(prdt.getDate(), evDts, cte);
        addDt(newdt, evDts, cte);
        return UpdateResult.getOkResult();
    } catch (WebdavException we) {
        throw we;
    } catch (Throwable t) {
        throw new WebdavException(t);
    }
}
Also used : BwDateTime(org.bedework.calfacade.BwDateTime) DateDatetimePropertyType(ietf.params.xml.ns.icalendar_2.DateDatetimePropertyType) WebdavException(org.bedework.webdav.servlet.shared.WebdavException) BwEvent(org.bedework.calfacade.BwEvent) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry)

Example 5 with ChangeTableEntry

use of org.bedework.calfacade.util.ChangeTableEntry in project bw-calendar-engine by Bedework.

the class LocationPropUpdater method applyUpdate.

@Override
public UpdateResult applyUpdate(final UpdateInfo ui) throws WebdavException {
    try {
        final BwEvent ev = ui.getEvent();
        final ChangeTableEntry cte = ui.getCte();
        BwString val = new BwString(UpdaterUtil.getLang(ui.getProp()), ((TextPropertyType) ui.getProp()).getText());
        final BwLocation evLoc = ev.getLocation();
        BwString evVal = null;
        if (evLoc != null) {
            evVal = evLoc.getAddress();
        }
        if (ui.isRemove()) {
            if (evVal == null) {
                return new UpdateResult("Entity has no " + ui.getPropName() + " property - cannot remove");
            }
            val = null;
        } else if (ui.isAdd()) {
            if (evVal != null) {
                return new UpdateResult("Entity already has " + ui.getPropName() + " property - cannot add");
            }
        } else if (!ui.isChange()) {
            final ParameterUpdater.UpdateInfo langUpd = UpdaterUtil.findLangUpdate(ui.getParamUpdates());
            if (langUpd == null) {
                return new UpdateResult("No update specified for " + ui.getPropName());
            }
            String lang = val.getLang();
            if (langUpd.isRemove()) {
                lang = null;
            } else if (langUpd.isAdd()) {
                lang = ((TextParameterType) langUpd.getParam()).getText();
            } else if (langUpd.getUpdparam() != null) {
                lang = ((TextParameterType) langUpd.getUpdparam()).getText();
            }
            if (!Util.equalsString(lang, val.getLang())) {
                val = new BwString(lang, val.getValue());
            }
        } else {
            if (!val.equals(evVal)) {
                return new UpdateResult("Values don't match for update to " + ui.getPropName());
            }
            val = new BwString(UpdaterUtil.getLang(ui.getUpdprop()), ((TextPropertyType) ui.getUpdprop()).getText());
        }
        if (val == null) {
            cte.setDeleted(ev.getLocation());
            ev.setLocation(null);
        } else if (Util.cmpObjval(val, evVal) != 0) {
            BwLocation loc = ui.getIcalCallback().findLocation(val);
            if (loc == null) {
                loc = BwLocation.makeLocation();
                loc.setAddress(val);
                ui.getIcalCallback().addLocation(loc);
            }
            if (cte.setChanged(evLoc, loc)) {
                ev.setLocation(loc);
            }
        }
        return UpdateResult.getOkResult();
    } catch (final CalFacadeException cfe) {
        throw new WebdavException(cfe);
    }
}
Also used : BwLocation(org.bedework.calfacade.BwLocation) TextParameterType(ietf.params.xml.ns.icalendar_2.TextParameterType) WebdavException(org.bedework.webdav.servlet.shared.WebdavException) BwEvent(org.bedework.calfacade.BwEvent) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry) BwString(org.bedework.calfacade.BwString) BwString(org.bedework.calfacade.BwString) TextPropertyType(ietf.params.xml.ns.icalendar_2.TextPropertyType) ParameterUpdater(org.bedework.caldav.bwserver.ParameterUpdater) UpdateResult(org.bedework.caldav.server.sysinterface.SysIntf.UpdateResult) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException)

Aggregations

ChangeTableEntry (org.bedework.calfacade.util.ChangeTableEntry)32 BwEvent (org.bedework.calfacade.BwEvent)26 UpdateResult (org.bedework.caldav.server.sysinterface.SysIntf.UpdateResult)20 CalFacadeException (org.bedework.calfacade.exc.CalFacadeException)10 WebdavException (org.bedework.webdav.servlet.shared.WebdavException)10 BwDateTime (org.bedework.calfacade.BwDateTime)7 BwString (org.bedework.calfacade.BwString)7 BwXproperty (org.bedework.calfacade.BwXproperty)7 ChangeTable (org.bedework.calfacade.util.ChangeTable)7 BwAttendee (org.bedework.calfacade.BwAttendee)4 BwCategory (org.bedework.calfacade.BwCategory)4 DateDatetimePropertyType (ietf.params.xml.ns.icalendar_2.DateDatetimePropertyType)3 TextPropertyType (ietf.params.xml.ns.icalendar_2.TextPropertyType)3 Holder (javax.xml.ws.Holder)3 BwContact (org.bedework.calfacade.BwContact)3 BwEventProxy (org.bedework.calfacade.BwEventProxy)3 BigInteger (java.math.BigInteger)2 HashMap (java.util.HashMap)2 TreeSet (java.util.TreeSet)2 BwOrganizer (org.bedework.calfacade.BwOrganizer)2