Search in sources :

Example 41 with EventInfo

use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.

the class InReply method process.

@Override
public ProcessResult process(final EventInfo ei) throws CalFacadeException {
    /* Process a response we as the organizer, or their proxy, received from
     * an attendee
     */
    final ProcessResult pr = new ProcessResult();
    final SchedulingI sched = getSvc().getScheduler();
    BwEvent ev = ei.getEvent();
    final EventInfo colEi = sched.getStoredMeeting(ev);
    /* The event should have a calendar set to the inbox it came from.
     * That inbox may be owned by somebody other than the current user if a
     * calendar user has delegated control of their inbox to some other user
     * e.g. secretary.
     */
    pr.attendeeAccepting = true;
    check: {
        if (colEi == null) {
            // No corresponding stored meeting
            break check;
        }
        if (ev.getOriginator() == null) {
            pr.sr.errorCode = CalFacadeException.schedulingNoOriginator;
            break check;
        }
        String attUri = null;
        /* Should be exactly one attendee */
        if (!ev.getSuppressed()) {
            final Collection<BwAttendee> atts = ev.getAttendees();
            if ((atts == null) || (atts.size() != 1)) {
                pr.sr.errorCode = CalFacadeException.schedulingExpectOneAttendee;
                break check;
            }
            final BwAttendee att = atts.iterator().next();
            if (!att.getPartstat().equals(acceptPartstat)) {
                pr.attendeeAccepting = false;
            }
            attUri = att.getAttendeeUri();
        }
        if (ei.getNumOverrides() > 0) {
            for (final EventInfo oei : ei.getOverrides()) {
                ev = oei.getEvent();
                final Collection<BwAttendee> atts = ev.getAttendees();
                if ((atts == null) || (atts.size() != 1)) {
                    pr.sr.errorCode = CalFacadeException.schedulingExpectOneAttendee;
                    break check;
                }
                final BwAttendee att = atts.iterator().next();
                if (!att.getPartstat().equals(acceptPartstat)) {
                    pr.attendeeAccepting = false;
                }
                if (attUri == null) {
                    attUri = att.getAttendeeUri();
                } else if (!attUri.equals(att.getAttendeeUri())) {
                    pr.sr.errorCode = CalFacadeException.schedulingExpectOneAttendee;
                    break check;
                }
            }
        }
        if (attUri == null) {
            pr.sr.errorCode = CalFacadeException.schedulingExpectOneAttendee;
            break check;
        }
        /*TODO If the sequence of the incoming event is lower than the sequence on the
       * calendar event we ignore it.
       */
        final boolean vpoll = colEi.getEvent().getEntityType() == IcalDefs.entityTypeVpoll;
        if (vpoll) {
            if (!updateOrganizerPollCopy(colEi, ei, attUri, pr.sr)) {
                break check;
            }
        } else if (!updateOrganizerCopy(colEi, ei, attUri, pr.sr)) {
            break check;
        }
        pr.removeInboxEntry = false;
    }
    return pr;
}
Also used : EventInfo(org.bedework.calfacade.svc.EventInfo) BwEvent(org.bedework.calfacade.BwEvent) SchedulingI(org.bedework.calsvci.SchedulingI) BwAttendee(org.bedework.calfacade.BwAttendee)

Example 42 with EventInfo

use of org.bedework.calfacade.svc.EventInfo 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 43 with EventInfo

use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.

the class ImplicitSchedulingHandler method implicitSchedule.

@Override
public void implicitSchedule(final EventInfo ei, final boolean noInvites) throws CalFacadeException {
    UpdateResult uer = ei.getUpdResult();
    if (debug) {
        dump(uer);
    }
    BwEvent ev = ei.getEvent();
    boolean organizerSchedulingObject = ev.getOrganizerSchedulingObject();
    boolean attendeeSchedulingObject = ev.getAttendeeSchedulingObject();
    if (ev.getSuppressed()) {
        if (!Util.isEmpty(ei.getOverrides())) {
            for (EventInfo oei : ei.getOverrides()) {
                uer = oei.getUpdResult();
                if (debug) {
                    dump(uer);
                }
                BwEvent oev = oei.getEvent();
                if (oev.getOrganizerSchedulingObject()) {
                    organizerSchedulingObject = true;
                }
                if (oev.getAttendeeSchedulingObject()) {
                    attendeeSchedulingObject = true;
                }
            }
        }
    }
    if (!organizerSchedulingObject && !attendeeSchedulingObject) {
        // Not a scheduling event
        if (debug) {
            trace("No a scheduling object: just return");
        }
        return;
    }
    if (ev.getOrganizer() == null) {
        throw new CalFacadeBadRequest(CalFacadeException.missingEventProperty);
    }
    if (ev.getOriginator() == null) {
        ev.setOriginator(ev.getOrganizer().getOrganizerUri());
    }
    if (uer.reply) {
        int meth;
        if (ei.getReplyAttendeeURI() != null) {
            meth = ScheduleMethods.methodTypeRefresh;
        } else {
            meth = ScheduleMethods.methodTypeReply;
        }
        ev.setScheduleMethod(meth);
        uer.schedulingResult = attendeeRespond(ei, meth);
        return;
    }
    if (uer.deleting) {
        if (organizerSchedulingObject) {
            // if (schedMethod == Icalendar.methodTypeCancel) {
            // /* We already canceled this one */
            // return;
            // }
            ev.setScheduleMethod(ScheduleMethods.methodTypeCancel);
        } else {
            // Reply from attendee setting partstat
            ev.setScheduleMethod(ScheduleMethods.methodTypeReply);
        }
    } else {
        ev.setScheduleMethod(ScheduleMethods.methodTypeRequest);
    }
    if (!noInvites) {
        uer.schedulingResult = schedule(ei, ei.getReplyAttendeeURI(), uer.fromAttUri, false);
    }
    if (!uer.adding && !Util.isEmpty(uer.deletedAttendees)) {
        /* Send cancel to removed attendees */
        for (BwAttendee att : uer.deletedAttendees) {
            if (Util.compareStrings(att.getPartstat(), IcalDefs.partstats[IcalDefs.partstatDeclined]) == 0) {
                // Already declined - send nothing
                continue;
            }
            /* Clone is adequate here. For a CANCEL we just send either the master
         * or the particular instance.
         */
            BwEvent cncl = (BwEvent) ev.clone();
            cncl.setAttendees(null);
            cncl.addAttendee((BwAttendee) att.clone());
            cncl.setRecipients(null);
            cncl.addRecipient(att.getAttendeeUri());
            cncl.setScheduleMethod(ScheduleMethods.methodTypeCancel);
            cncl.setOrganizerSchedulingObject(true);
            cncl.setAttendeeSchedulingObject(false);
            EventInfo cei = new EventInfo(cncl);
            ScheduleResult cnclr = schedule(cei, null, null, false);
            if (debug) {
                trace(cnclr.toString());
            }
        }
    }
    if (ei.getInboxEventName() != null) {
        // Delete the given event from the inbox.
        EventsI events = getSvc().getEventsHandler();
        BwCalendar inbox = getSvc().getCalendarsHandler().getSpecial(BwCalendar.calTypeInbox, true);
        final EventInfo inboxei = events.get(inbox.getPath(), ei.getInboxEventName());
        if (inboxei != null) {
            events.delete(inboxei, false);
        }
    }
}
Also used : CalFacadeBadRequest(org.bedework.calfacade.exc.CalFacadeBadRequest) ScheduleResult(org.bedework.calfacade.ScheduleResult) EventInfo(org.bedework.calfacade.svc.EventInfo) BwEvent(org.bedework.calfacade.BwEvent) BwCalendar(org.bedework.calfacade.BwCalendar) EventsI(org.bedework.calsvci.EventsI) BwAttendee(org.bedework.calfacade.BwAttendee) UpdateResult(org.bedework.calfacade.svc.EventInfo.UpdateResult)

Example 44 with EventInfo

use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.

the class OrganizerSchedulingHandler method declineCounter.

@Override
public ScheduleResult declineCounter(final EventInfo ei, final String comment, final BwAttendee fromAtt) throws CalFacadeException {
    final EventInfo outEi = copyEventInfo(ei, getPrincipal());
    final BwEvent ev = outEi.getEvent();
    ev.setScheduleMethod(ScheduleMethods.methodTypeDeclineCounter);
    if (comment != null) {
        ev.addComment(null, comment);
    }
    return schedule(outEi, fromAtt.getAttendeeUri(), null, false);
}
Also used : EventInfo(org.bedework.calfacade.svc.EventInfo) BwEvent(org.bedework.calfacade.BwEvent)

Example 45 with EventInfo

use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.

the class OutboundSchedulingHandler method addToInbox.

/**
 * Add a copy of senderEi to the users inbox and add to the autoschedule queue.
 * The 'sender' may be the organizer of a meeting, if it's REQUEST etc, or the
 * attendee replying.
 *
 * @param inboxPath - eventual destination
 * @param attPrincipal - attendees principal
 * @param senderEi the event
 * @param fromOrganizer - true if it's coming from the organizer
 * @return null for ok, errorcode otherwise
 * @throws CalFacadeException
 */
private String addToInbox(final String inboxPath, final BwPrincipal attPrincipal, final EventInfo senderEi, final boolean fromOrganizer) throws CalFacadeException {
    final EventInfo ei = copyEventInfo(senderEi, fromOrganizer, attPrincipal);
    final BwEvent ev = ei.getEvent();
    if (senderEi.getReplyUpdate()) {
        // Flag as a trivial update to attendee status
        ev.addXproperty(new BwXproperty(BwXproperty.bedeworkSchedulingReplyUpdate, null, "true"));
    }
    if (!Util.isEmpty(ev.getRecipients())) {
        ev.getRecipients().clear();
    }
    ev.addRecipient(getSvc().getDirectories().principalToCaladdr(attPrincipal));
    /*
    if (destAtt != null) {
      String attPartStat = destAtt.getPartstat();

      if ((attPartStat == null) ||   // default - needs-action
          (!attPartStat.equalsIgnoreCase(IcalDefs.partstatValAccepted) &&
           !attPartStat.equalsIgnoreCase(IcalDefs.partstatValCompleted) &&
           !attPartStat.equalsIgnoreCase(IcalDefs.partstatValDelegated))) {
        ev.setTransparency(IcalDefs.transparencyTransparent);
      }
    }*/
    final String evDtstamp = ev.getDtstamp();
    ev.setScheduleState(BwEvent.scheduleStateNotProcessed);
    ev.setColPath(inboxPath);
    if (ei.getNumContainedItems() > 0) {
        for (final EventInfo cei : ei.getContainedItems()) {
            cei.getEvent().setColPath(inboxPath);
        }
    }
    /* Before we add this we should see if there is an earlier one we can
     * discard. As attendees update their status we get many requests sent to
     * each attendee.
     *
     * Also this current message may be earlier than one already in the inbox.
     *
     * TODO - fix recurrences
     *
     * We could get separate messages for the same uid but with different
     * recurrence ids if we are an attendee to some instances only.
     *
     * In the inbox these will be separate events with the same uid -
     * possibly, They probably need to be combined in the users
     * calendar as a single recurring event.
     */
    final int smethod = ev.getScheduleMethod();
    if (Icalendar.itipRequestMethodType(smethod)) {
        final Collection<EventInfo> inevs = getEventsByUid(inboxPath, ev.getUid());
        for (final EventInfo inei : inevs) {
            final BwEvent inev = inei.getEvent();
            final int cres = evDtstamp.compareTo(inev.getDtstamp());
            if (cres <= 0) {
                // Discard the new one
                return null;
            }
            /* Discard the earlier message */
            /* XXX What if this message is currently being processed by the inbox
         * handler process? Does it matter - will it reappear?
         *
         * Probably need to handle stale-state exceptions at the other end.
         */
            deleteEvent(inei, true, false);
        }
    }
    /* Add it and post to the autoscheduler */
    final String ecode = addEvent(ei, "In-" + Uid.getUid() + "-" + evDtstamp, BwCalendar.calTypePendingInbox, true);
    if (ecode != null) {
        return ecode;
    }
    if (debug) {
        trace("Add event with name " + ev.getName() + " and summary " + ev.getSummary() + " to " + ev.getColPath());
    }
    addAutoScheduleMessage(true, attPrincipal.getPrincipalRef(), ev.getName());
    return null;
}
Also used : EventInfo(org.bedework.calfacade.svc.EventInfo) BwXproperty(org.bedework.calfacade.BwXproperty) BwEvent(org.bedework.calfacade.BwEvent)

Aggregations

EventInfo (org.bedework.calfacade.svc.EventInfo)111 BwEvent (org.bedework.calfacade.BwEvent)80 CalFacadeException (org.bedework.calfacade.exc.CalFacadeException)37 BwCalendar (org.bedework.calfacade.BwCalendar)27 BwEventProxy (org.bedework.calfacade.BwEventProxy)24 BwAttendee (org.bedework.calfacade.BwAttendee)19 ArrayList (java.util.ArrayList)16 CoreEventInfo (org.bedework.calcorei.CoreEventInfo)15 BwEventAnnotation (org.bedework.calfacade.BwEventAnnotation)15 BwString (org.bedework.calfacade.BwString)11 BwDateTime (org.bedework.calfacade.BwDateTime)10 BwEventObj (org.bedework.calfacade.BwEventObj)10 TreeSet (java.util.TreeSet)9 BwXproperty (org.bedework.calfacade.BwXproperty)9 BwPrincipal (org.bedework.calfacade.BwPrincipal)7 CalFacadeAccessException (org.bedework.calfacade.exc.CalFacadeAccessException)7 WebdavException (org.bedework.webdav.servlet.shared.WebdavException)7 Calendar (net.fortuna.ical4j.model.Calendar)6 Period (net.fortuna.ical4j.model.Period)6 BwOrganizer (org.bedework.calfacade.BwOrganizer)6