Search in sources :

Example 11 with ChangeTableEntry

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

the class RelatedToPropUpdater method applyUpdate.

public UpdateResult applyUpdate(final UpdateInfo ui) throws WebdavException {
    ChangeTableEntry cte = ui.getCte();
    BwEvent ev = ui.getEvent();
    RelatedToPropType pr = (RelatedToPropType) ui.getProp();
    ReltypeParamType rtparm = (ReltypeParamType) UpdaterUtil.getParam(pr, XcalTags.reltype);
    String propRelType = "";
    String propValType;
    String propVal;
    if (rtparm != null) {
        propRelType = rtparm.getText();
    }
    if (pr.getText() != null) {
        propValType = "";
        propVal = pr.getText();
    } else if (pr.getUri() != null) {
        propValType = "URI";
        propVal = pr.getUri();
    } else {
        propValType = "UID";
        propVal = pr.getUid();
    }
    /* We encode related to (maybe) as triples - reltype, value-type, value */
    String[] info = null;
    BwXproperty xprop = null;
    BwRelatedTo relto = ev.getRelatedTo();
    if (relto != null) {
        info = new String[3];
        info[0] = relto.getRelType();
        // default
        info[1] = "";
        info[2] = relto.getValue();
    } else {
        xprop = ev.findXproperty(BwXproperty.bedeworkRelatedTo);
        if (xprop != null) {
            String relx = xprop.getValue();
            if (relx != null) {
                info = Util.decodeArray(relx);
            }
        }
    }
    int pos = findRT(info, propRelType, propValType, propVal);
    if (ui.isAdd()) {
        if (pos >= 0) {
            // Already there
            return UpdateResult.getOkResult();
        }
        int iPos = info.length;
        info = Arrays.copyOf(info, info.length + 3);
        info[iPos] = propRelType;
        info[iPos + 1] = propValType;
        info[iPos + 2] = propVal;
        ev.setRelatedTo(null);
        if (xprop == null) {
            xprop = new BwXproperty(BwXproperty.bedeworkRelatedTo, null, null);
            ev.addXproperty(xprop);
        }
        String newval = Util.encodeArray(info);
        xprop.setValue(newval);
        cte.addAddedValue(newval);
        return UpdateResult.getOkResult();
    }
    if (ui.isRemove()) {
        if (pos < 0) {
            // Nothing to remove
            return UpdateResult.getOkResult();
        }
        if (info.length == 3) {
            // removing only related-to
            ev.setRelatedTo(null);
            ev.removeXproperties(BwXproperty.bedeworkRelatedTo);
            return UpdateResult.getOkResult();
        }
        String[] newInfo = new String[info.length - 3];
        for (int i = 0; i < pos; i++) {
            newInfo[i] = info[i];
        }
        for (int i = pos + 3; i < info.length; i++) {
            newInfo[i] = info[i];
        }
        ev.setRelatedTo(null);
        if (xprop == null) {
            xprop = new BwXproperty(BwXproperty.bedeworkRelatedTo, null, null);
            ev.addXproperty(xprop);
        }
        String newval = Util.encodeArray(newInfo);
        xprop.setValue(newval);
        cte.addRemovedValue(newval);
        return UpdateResult.getOkResult();
    }
    if (ui.isChange()) {
        // Change a value
        if (pos < 0) {
            // Nothing to change
            return new UpdateResult("No comment to change");
        }
        info[pos] = propRelType;
        info[pos + 1] = propValType;
        info[pos + 2] = propVal;
        ev.setRelatedTo(null);
        if (xprop == null) {
            xprop = new BwXproperty(BwXproperty.bedeworkRelatedTo, null, null);
            ev.addXproperty(xprop);
        }
        String newval = Util.encodeArray(info);
        xprop.setValue(newval);
        cte.addChangedValue(newval);
        return UpdateResult.getOkResult();
    }
    return UpdateResult.getOkResult();
}
Also used : RelatedToPropType(ietf.params.xml.ns.icalendar_2.RelatedToPropType) BwRelatedTo(org.bedework.calfacade.BwRelatedTo) BwXproperty(org.bedework.calfacade.BwXproperty) ReltypeParamType(ietf.params.xml.ns.icalendar_2.ReltypeParamType) BwEvent(org.bedework.calfacade.BwEvent) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry) UpdateResult(org.bedework.caldav.server.sysinterface.SysIntf.UpdateResult)

Example 12 with ChangeTableEntry

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

the class TranspPropUpdater method applyUpdate.

@Override
public UpdateResult applyUpdate(final UpdateInfo ui) throws WebdavException {
    BwEvent ev = ui.getEvent();
    TranspPropType pr = (TranspPropType) ui.getProp();
    ChangeTableEntry cte = ui.getCte();
    String val = pr.getText();
    String evVal = ev.getTransparency();
    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()) {
        return new UpdateResult("No update specified for " + ui.getPropName());
    } else {
        if (!val.equals(evVal)) {
            return new UpdateResult("Values don't match for update to " + ui.getPropName());
        }
        val = ((TranspPropType) ui.getUpdprop()).getText();
    }
    if (!Util.equalsString(val, evVal)) {
        cte.setChanged(evVal, val);
        ev.setTransparency(val);
    }
    return UpdateResult.getOkResult();
}
Also used : TranspPropType(ietf.params.xml.ns.icalendar_2.TranspPropType) BwEvent(org.bedework.calfacade.BwEvent) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry) UpdateResult(org.bedework.caldav.server.sysinterface.SysIntf.UpdateResult)

Example 13 with ChangeTableEntry

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

the class CoreEvents method updateRecurrences.

/* XXX This is a bit brute force but it will do for the moment. We have to
   * turn a set of rules into a set of changes. If we'd preserved the rules
   * prior to this I guess we could figure out the differences without querying
   * the db.
   *
   * For the moment create a whole set of instances and then query the db to see if
   * they match.
   */
@SuppressWarnings("unchecked")
private void updateRecurrences(final EventInfo ei, final UpdateEventResult uc, final Collection<BwEventProxy> overrides, final boolean shared) throws CalFacadeException {
    final BwEvent val = ei.getEvent();
    final ChangeTable changes = val.getChangeset(currentPrincipal());
    if (!changes.isEmpty()) {
        if (!changes.recurrenceChanged()) {
            return;
        }
        if (!changes.recurrenceRulesChanged()) {
            // We can handle exdate and rdate changes.
            ChangeTableEntry ent = changes.getEntry(PropertyInfoIndex.EXDATE);
            if (ent.getAddedValues() != null) {
                // exdates added - remove the instances.
                removeInstances(val, uc, overrides, ent.getAddedValues(), shared);
            }
            if (ent.getRemovedValues() != null) {
                // exdates removed - add the instances.
                addInstances(val, uc, overrides, ent.getRemovedValues(), shared);
            }
            ent = changes.getEntry(PropertyInfoIndex.RDATE);
            if (ent.getAddedValues() != null) {
                // rdates added - add the instances.
                addInstances(val, uc, overrides, ent.getAddedValues(), shared);
            }
            if (ent.getRemovedValues() != null) {
                // rdates removed - remove the instances.
                removeInstances(val, uc, overrides, ent.getRemovedValues(), shared);
            }
            return;
        }
    }
    final Map<String, BwRecurrenceInstance> updated = new HashMap<>();
    /* Get all the times for this event. - this could be a problem. Need to
       limit the number. Should we do this in chunks, stepping through the
       whole period?
     */
    final RecurPeriods rp = RecurUtil.getPeriods(val, getAuthprops().getMaxYears(), getAuthprops().getMaxInstances());
    if (rp.instances.isEmpty()) {
        // No instances for an alleged recurring event.
        // XXX Mark the master as non-recurring to stop it disappearing
        val.setRecurring(false);
    // throwException(CalFacadeException.noRecurrenceInstances);
    }
    final String stzid = val.getDtstart().getTzid();
    /*    try {
      val.setLatestDate(Timezones.getUtc(rp.rangeEnd.toString(), stzid));
    } catch (Throwable t) {
      throwException(new CalFacadeException(t));
    } */
    int maxInstances = getAuthprops().getMaxInstances();
    final boolean dateOnly = val.getDtstart().getDateType();
    for (final Period p : rp.instances) {
        String dtval = p.getStart().toString();
        if (dateOnly) {
            dtval = dtval.substring(0, 8);
        }
        final BwDateTime rstart = BwDateTime.makeBwDateTime(dateOnly, dtval, stzid);
        dtval = p.getEnd().toString();
        if (dateOnly) {
            dtval = dtval.substring(0, 8);
        }
        final BwDateTime rend = BwDateTime.makeBwDateTime(dateOnly, dtval, stzid);
        final BwRecurrenceInstance ri = new BwRecurrenceInstance();
        ri.setDtstart(rstart);
        ri.setDtend(rend);
        ri.setRecurrenceId(ri.getDtstart().getDate());
        ri.setMaster(val);
        updated.put(ri.getRecurrenceId(), ri);
        maxInstances--;
        if (maxInstances == 0) {
            // That's all you're getting from me
            break;
        }
    }
    final List<BwRecurrenceInstance> current = dao.getInstances(val);
    for (final BwRecurrenceInstance ri : current) {
        final BwRecurrenceInstance updri = updated.get(ri.getRecurrenceId());
        if (updri == null) {
            // Not in the new instance set - delete from db
            ei.removeOverride(ri.getRecurrenceId());
            dao.delete(ri);
            uc.addDeleted(ri);
            notifyInstanceChange(SysEvent.SysCode.ENTITY_DELETED, val, shared, ri.getRecurrenceId());
            continue;
        }
        /* Found instance with same recurrence id. Is the start and end the same
         */
        if (!ri.getDtstart().equals(updri.getDtstart()) || !ri.getDtend().equals(updri.getDtend())) {
            ri.setDtstart(updri.getDtstart());
            ri.setDtend(updri.getDtend());
            dao.update(ri);
            uc.addUpdated(ri);
            notifyInstanceChange(SysEvent.SysCode.ENTITY_UPDATED, val, shared, ri.getRecurrenceId());
        }
        // Remove the entry - we've processed it.
        updated.remove(ri.getRecurrenceId());
    }
    for (final BwRecurrenceInstance ri : updated.values()) {
        dao.save(ri);
        uc.addAdded(ri);
        notifyInstanceChange(SysEvent.SysCode.ENTITY_ADDED, val, shared, ri.getRecurrenceId());
    }
}
Also used : BwDateTime(org.bedework.calfacade.BwDateTime) HashMap(java.util.HashMap) Period(net.fortuna.ical4j.model.Period) BwEvent(org.bedework.calfacade.BwEvent) BwRecurrenceInstance(org.bedework.calfacade.BwRecurrenceInstance) ChangeTable(org.bedework.calfacade.util.ChangeTable) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry) RecurPeriods(org.bedework.icalendar.RecurUtil.RecurPeriods)

Example 14 with ChangeTableEntry

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

the class InReply method updateOrganizerCopy.

private boolean updateOrganizerCopy(final EventInfo colEi, final EventInfo inBoxEi, final String attUri, final ScheduleResult sr) throws CalFacadeException {
    final BwEvent inBoxEv = inBoxEi.getEvent();
    final BwEvent calEv = colEi.getEvent();
    final ChangeTable chg = calEv.getChangeset(getPrincipalHref());
    /* Only set true if the inbox copy needs to stay as notification.
     * Do not set true for status updates
     */
    boolean changed = false;
    if (debug) {
        trace("Update for attendee " + attUri);
    }
    if (inBoxEv.getScheduleMethod() != ScheduleMethods.methodTypeReply) {
        sr.errorCode = CalFacadeException.schedulingBadMethod;
        return false;
    }
    /* If the incoming sequence is less than that in the organizers event
     * then ignore the incoming reply?
     */
    /* Update the participation status from the incoming attendee */
    BwAttendee calAtt;
    final ChangeTableEntry cte = chg.getEntry(PropertyIndex.PropertyInfoIndex.ATTENDEE);
    if (!inBoxEv.getSuppressed()) {
        calAtt = calEv.findAttendee(attUri);
        if (calAtt == null) {
            if (debug) {
                trace("Not an attendee of " + calEv);
            }
            sr.errorCode = CalFacadeException.schedulingUnknownAttendee;
            sr.extraInfo = attUri;
            return false;
        }
        // For a recurring instance we replace or we update all recurring instances.
        final boolean recurringInstance = (calEv instanceof BwEventProxy);
        final BwAttendee att = inBoxEv.findAttendee(attUri);
        if (calAtt.changedBy(att)) {
            changed = true;
            if (recurringInstance) {
                calEv.removeAttendee(att);
                calAtt = (BwAttendee) att.clone();
            } else {
                att.copyTo(calAtt);
            }
            cte.addChangedValue(calAtt);
        }
        calAtt.setScheduleStatus(getRstat(inBoxEv));
        if (recurringInstance) {
            calEv.addAttendee(calAtt);
        }
        // XXX Ensure no name change
        if (calEv instanceof BwEventProxy) {
            final BwEventProxy pr = (BwEventProxy) calEv;
            final BwEventAnnotation ann = pr.getRef();
            ann.setName(null);
        }
    }
    /* The above changed the master - now we need to update or add any overrides
     */
    if (calEv.getRecurring() && (inBoxEi.getOverrides() != null)) {
        for (final EventInfo oei : inBoxEi.getOverrides()) {
            final BwEvent oev = oei.getEvent();
            final EventInfo cei = colEi.findOverride(oev.getRecurrenceId());
            /*
        if (cei == null) {
          // Organizer must have deleted the override.
          if (debug) {
            trace("Skipping missing override " + oev.getRecurrenceId());
          }
          continue;
        }*/
            final BwEvent ocalEv = cei.getEvent();
            if (((BwEventProxy) ocalEv).getRef().unsaved()) {
                // New Override
                try {
                    final String rid = oev.getRecurrenceId();
                    Date dt = new DateTime(rid);
                    if (calEv.getDtstart().getDateType()) {
                        // RECUR - fix all day recurrences sometime
                        if (rid.length() > 8) {
                            // Try to fix up bad all day recurrence ids. - assume a local timezone
                            ((DateTime) dt).setTimeZone(null);
                            dt = new Date(dt.toString().substring(0, 8));
                        }
                    }
                    final DtStart st = new DtStart(dt);
                    final String tzid = calEv.getDtstart().getTzid();
                    if (tzid != null) {
                        final TimeZone tz = Timezones.getTz(tzid);
                        st.setTimeZone(tz);
                    }
                    ocalEv.setDtstart(BwDateTime.makeBwDateTime(st));
                    ocalEv.setDuration(calEv.getDuration());
                    ocalEv.setDtend(ocalEv.getDtstart().addDur(new Dur(calEv.getDuration())));
                } catch (final CalFacadeException cfe) {
                    throw cfe;
                } catch (final Throwable t) {
                    throw new CalFacadeException(t);
                }
            }
            final BwAttendee ovatt = oev.findAttendee(attUri);
            calAtt = ocalEv.findAttendee(attUri);
            if (calAtt == null) {
                // Organizer must have removed the attendee.
                if (debug) {
                    trace("Skipping override " + attUri + " is not attending");
                }
                continue;
            }
            if (calAtt.changedBy(ovatt)) {
                changed = true;
                ocalEv.removeAttendee(ovatt);
                calAtt = (BwAttendee) ovatt.clone();
                calAtt.setScheduleStatus(getRstat(oev));
                ocalEv.addAttendee(calAtt);
                cte.addChangedValue(calAtt);
            }
        }
    }
    final boolean noinvites = !changed;
    colEi.setReplyUpdate(true);
    /* Update the organizer copy. This will broadcast the changes tp all
     * attendees
     */
    getSvc().getEventsHandler().update(colEi, noinvites, attUri);
    return changed;
}
Also used : Dur(net.fortuna.ical4j.model.Dur) EventInfo(org.bedework.calfacade.svc.EventInfo) BwEvent(org.bedework.calfacade.BwEvent) BwEventProxy(org.bedework.calfacade.BwEventProxy) Date(net.fortuna.ical4j.model.Date) DateTime(net.fortuna.ical4j.model.DateTime) BwDateTime(org.bedework.calfacade.BwDateTime) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) TimeZone(net.fortuna.ical4j.model.TimeZone) DtStart(net.fortuna.ical4j.model.property.DtStart) BwEventAnnotation(org.bedework.calfacade.BwEventAnnotation) ChangeTable(org.bedework.calfacade.util.ChangeTable) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry) BwAttendee(org.bedework.calfacade.BwAttendee)

Example 15 with ChangeTableEntry

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

the class InRequest method updateAttendeeFields.

private boolean updateAttendeeFields(final EventInfo ourCopy, final EventInfo inBoxEi, final String attUri) throws CalFacadeException {
    BwEvent ourEv = ourCopy.getEvent();
    BwEvent inEv = inBoxEi.getEvent();
    boolean flagNeedsReply = false;
    ChangeTable chg = ourCopy.getChangeset(getPrincipalHref());
    for (PropertyInfoIndex ipi : PropertyInfoIndex.values()) {
        BwIcalPropertyInfoEntry bipie = BwIcalPropertyInfo.getPinfo(ipi);
        if (bipie == null) {
            continue;
        }
        if ((ourEv.getEntityType() == IcalDefs.entityTypeEvent) && !bipie.getEventProperty()) {
            continue;
        }
        if ((ourEv.getEntityType() == IcalDefs.entityTypeTodo) && !bipie.getTodoProperty()) {
            continue;
        }
        switch(ipi) {
            case UNKNOWN_PROPERTY:
                break;
            case CLASS:
                if (chg.changed(ipi, ourEv.getClassification(), inEv.getClassification())) {
                    ourEv.setClassification(inEv.getClassification());
                }
                break;
            case COMPLETED:
                /* Todo only */
                if (chg.changed(ipi, ourEv.getCompleted(), inEv.getCompleted())) {
                    ourEv.setCompleted(inEv.getCompleted());
                }
                break;
            case CREATED:
                break;
            case DESCRIPTION:
                /*
          for (BwLongString s: inEv.getDescriptions()) {
            chg.addValue(Property.DESCRIPTION, s);
          }
          */
                if (chg.changed(ipi, ourEv.getDescription(), inEv.getDescription())) {
                    ourEv.setDescription(inEv.getDescription());
                }
                break;
            case DTEND:
            /* Event only */
            case DUE:
                /* Todo only */
                BwDateTime dt = inEv.getDtend();
                if (!CalFacadeUtil.eqObjval(ourEv.getDtend(), dt)) {
                    ourEv.setDtend(dt);
                    chg.changed(ipi, ourEv.getDtend(), dt);
                }
                char c = inEv.getEndType();
                if (c != ourEv.getEndType()) {
                    ourEv.setEndType(c);
                    chg.changed(PropertyInfoIndex.END_TYPE, ourEv.getEndType(), c);
                }
                break;
            case DTSTAMP:
                break;
            case DTSTART:
                dt = inEv.getDtstart();
                if (!CalFacadeUtil.eqObjval(ourEv.getDtstart(), dt)) {
                    ourEv.setDtstart(dt);
                    chg.changed(ipi, ourEv.getDtstart(), dt);
                }
                break;
            case DURATION:
                if (chg.changed(ipi, ourEv.getDuration(), inEv.getDuration())) {
                    ourEv.setDuration(inEv.getDuration());
                }
                break;
            case GEO:
                if (chg.changed(ipi, ourEv.getGeo(), inEv.getGeo())) {
                    ourEv.setGeo(inEv.getGeo());
                }
                break;
            case LAST_MODIFIED:
                break;
            case LOCATION:
                if (chg.changed(ipi, ourEv.getLocation(), inEv.getLocation())) {
                    ourEv.setLocation((BwLocation) inEv.getLocation().clone());
                }
                break;
            case ORGANIZER:
                if (chg.changed(ipi, ourEv.getOrganizer(), inEv.getOrganizer())) {
                    ourEv.setOrganizer((BwOrganizer) inEv.getOrganizer().clone());
                }
                break;
            case PRIORITY:
                if (chg.changed(ipi, ourEv.getPriority(), inEv.getPriority())) {
                    ourEv.setPriority(inEv.getPriority());
                }
                break;
            case RECURRENCE_ID:
                break;
            case SEQUENCE:
                if (chg.changed(ipi, ourEv.getSequence(), inEv.getSequence())) {
                    ourEv.setSequence(inEv.getSequence());
                }
                break;
            case STATUS:
                if (chg.changed(ipi, ourEv.getStatus(), inEv.getStatus())) {
                    ourEv.setStatus(inEv.getStatus());
                }
                break;
            case SUMMARY:
                /*
          for (BwString s: inEv.getSummaries()) {
            chg.addValue(Property.SUMMARY, s);
          }
          */
                if (chg.changed(ipi, ourEv.getSummary(), inEv.getSummary())) {
                    ourEv.setSummary(inEv.getSummary());
                }
                break;
            case PERCENT_COMPLETE:
                /* Todo only */
                if (chg.changed(ipi, ourEv.getPercentComplete(), inEv.getPercentComplete())) {
                    ourEv.setPercentComplete(inEv.getPercentComplete());
                }
                break;
            case UID:
                break;
            case URL:
                if (chg.changed(ipi, ourEv.getLink(), inEv.getLink())) {
                    ourEv.setLink(inEv.getLink());
                }
                break;
            case TRANSP:
                /* Event only - done with attendee */
                break;
            case ATTACH:
                break;
            case ATTENDEE:
                String transparency = ourEv.getTransparency();
                BwAttendee ourAtt = null;
                for (BwAttendee inAtt : inEv.getAttendees()) {
                    BwAttendee att = (BwAttendee) inAtt.clone();
                    att.setScheduleStatus(null);
                    String inAttUri = att.getAttendeeUri();
                    BwAttendee evAtt = ourEv.findAttendee(inAttUri);
                    if (inAttUri.equals(attUri)) {
                        // It's ours
                        ourAtt = att;
                        if ((att.getPartstat() == null) || att.getPartstat().equals(IcalDefs.partstatValNeedsAction)) {
                            transparency = IcalDefs.transparencyTransparent;
                            // Apple ical seems to expect an x-prop.
                            flagNeedsReply = true;
                        }
                    // att.setScheduleStatus(IcalDefs.deliveryStatusSuccess);
                    }
                    /* See if it's in the current set and if anything significant changed

            for (BwAttendee calAtt: ourEv.getAttendees()) {
              if (calAtt.getAttendeeUri().equals(inAttUri)) {
                if (calAtt.changedBy(inAtt, false)) {
                  ourEv.setSignificantChange(true);
                }
              }
            }*/
                    final ChangeTableEntry cte = chg.getEntry(PropertyInfoIndex.ATTENDEE);
                    if (evAtt != null) {
                        cte.addChangedValue(att);
                    } else {
                        cte.addAddedValue(att);
                    }
                }
                if (ourAtt == null) {
                    // Error?
                    if (debug) {
                        trace("InSchedule - no attendee for " + ourEv.getOwnerHref());
                    }
                    return false;
                }
                if (chg.changed(PropertyInfoIndex.TRANSP, ourEv.getTransparency(), transparency)) {
                    ourEv.setTransparency(transparency);
                }
                break;
            case CATEGORIES:
                if (!Util.isEmpty(inEv.getCategories())) {
                    for (BwCategory cat : inEv.getCategories()) {
                        chg.addValue(ipi, cat);
                    }
                }
                break;
            case COMMENT:
                for (BwString s : inEv.getComments()) {
                    chg.addValue(ipi, s);
                }
                break;
            case CONTACT:
                for (final BwContact ct : inEv.getContacts()) {
                    chg.addValue(ipi, ct.clone());
                }
                break;
            case EXDATE:
                // Don't updaye exdate - we add cancelled overrides
                break;
            case EXRULE:
                // Only for master events
                if (ourEv instanceof BwEventProxy) {
                    break;
                }
                for (final String s : inEv.getExrules()) {
                    chg.addValue(ipi, s);
                }
                break;
            case REQUEST_STATUS:
                break;
            case RELATED_TO:
                if (chg.changed(ipi, ourEv.getRelatedTo(), inEv.getRelatedTo())) {
                    ourEv.setRelatedTo(inEv.getRelatedTo());
                }
                break;
            case RESOURCES:
                for (BwString bs : inEv.getResources()) {
                    chg.addValue(ipi, bs);
                }
                break;
            case RDATE:
                // Only for master events
                if (ourEv instanceof BwEventProxy) {
                    break;
                }
                for (BwDateTime bdt : inEv.getRdates()) {
                    chg.addValue(ipi, bdt);
                }
                break;
            case RRULE:
                // Only for master events
                if (ourEv instanceof BwEventProxy) {
                    break;
                }
                for (String s : inEv.getRrules()) {
                    chg.addValue(ipi, s);
                }
                break;
            case XPROP:
                for (BwXproperty x : inEv.getXproperties()) {
                    chg.addValue(ipi, x);
                }
                break;
            case FREEBUSY:
            case TZID:
            case TZNAME:
            case TZOFFSETFROM:
            case TZOFFSETTO:
            case TZURL:
            case ACTION:
            case REPEAT:
            case TRIGGER:
                break;
            // non ical
            case COLLECTION:
            // non ical
            case COST:
            // non ical
            case CREATOR:
            // non ical
            case OWNER:
            case // non ical
            ENTITY_TYPE:
                break;
            case // Component
            VALARM:
                break;
            // Param
            case LANG:
            case // Param
            TZIDPAR:
                break;
            case PUBLISH_URL:
            case POLL_ITEM_ID:
            case END_TYPE:
            case ETAG:
            case HREF:
            case XBEDEWORK_COST:
            case CALSCALE:
            case METHOD:
            case PRODID:
            case VERSION:
            case ACL:
            case AFFECTS_FREE_BUSY:
            case ALIAS_URI:
            case ATTENDEE_SCHEDULING_OBJECT:
            case CALTYPE:
            case COL_PROPERTIES:
            case COLPATH:
            case CTOKEN:
            case DISPLAY:
            case DOCTYPE:
            case EVENTREG_END:
            case EVENTREG_MAX_TICKETS:
            case EVENTREG_MAX_TICKETS_PER_USER:
            case EVENTREG_START:
            case EVENTREG_WAIT_LIST_LIMIT:
            case FILTER_EXPR:
            case IGNORE_TRANSP:
            case IMAGE:
            case INDEX_END:
            case INDEX_START:
            case INSTANCE:
            case LAST_REFRESH:
            case LAST_REFRESH_STATUS:
            case LOCATION_UID:
            case LOCATION_STR:
                break;
            default:
                warn("Not handling icalendar property " + ipi);
        }
    // switch
    }
    if (chg.changed(PropertyInfoIndex.COST, ourEv.getCost(), inEv.getCost())) {
        ourEv.setCost(inEv.getCost());
    }
    /* Now see if we need to flag a schedule-tag change. We do so only if
     * a. A property other than the attendee changed
     * b. An attendee was added or removed
     */
    Collection<ChangeTableEntry> changes = chg.getEntries();
    ChangeTableEntry attChanges = null;
    ourEv.setSignificantChange(false);
    for (ChangeTableEntry cte : changes) {
        if (!cte.getChanged()) {
            continue;
        }
        if (cte.getIndex() == PropertyInfoIndex.ATTENDEE) {
            attChanges = cte;
            continue;
        }
        ourEv.setSignificantChange(true);
    }
    if (debug) {
        trace("After change check getSignificantChange=" + ourEv.getSignificantChange());
    }
    if (flagNeedsReply) {
    // Apple ical seems to expect an x-prop.
    // chg.addValue(PropertyInfoIndex.XPROP,
    // new BwXproperty(BwXproperty.appleNeedsReply,
    // null, "TRUE"));
    }
    chg.processChanges(ourEv, true);
    if (debug) {
        trace(chg.toString());
    }
    /* The attendee change entry will now reflect the changes made to the
     * attendee list. See if any significant change was made there.
     */
    if (attChanges != null) {
        if (!Util.isEmpty(attChanges.getAddedValues()) || !Util.isEmpty(attChanges.getRemovedValues())) {
            ourEv.setSignificantChange(true);
        } else {
        /* TODO - go through the changed entries and look for our entry. See
         * if we are being asked to reply - this can probably be done earlier.
         */
        }
    }
    if (debug) {
        trace("After attendee change check getSignificantChange=" + ourEv.getSignificantChange());
    }
    return true;
}
Also used : BwDateTime(org.bedework.calfacade.BwDateTime) BwCategory(org.bedework.calfacade.BwCategory) BwEvent(org.bedework.calfacade.BwEvent) BwString(org.bedework.calfacade.BwString) BwString(org.bedework.calfacade.BwString) BwContact(org.bedework.calfacade.BwContact) BwEventProxy(org.bedework.calfacade.BwEventProxy) PropertyInfoIndex(org.bedework.util.calendar.PropertyIndex.PropertyInfoIndex) BwIcalPropertyInfoEntry(org.bedework.calfacade.ical.BwIcalPropertyInfo.BwIcalPropertyInfoEntry) BwXproperty(org.bedework.calfacade.BwXproperty) ChangeTable(org.bedework.calfacade.util.ChangeTable) ChangeTableEntry(org.bedework.calfacade.util.ChangeTableEntry) BwAttendee(org.bedework.calfacade.BwAttendee)

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