Search in sources :

Example 6 with BwEventProxy

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

the class Events method postProcess.

private EventInfo postProcess(final CoreEventInfo cei) throws CalFacadeException {
    if (cei == null) {
        return null;
    }
    // trace("ev: " + ev);
    /* If the event is an event reference (an alias) implant it in an event
     * proxy and return that object.
     */
    BwEvent ev = cei.getEvent();
    if (ev instanceof BwEventAnnotation) {
        ev = new BwEventProxy((BwEventAnnotation) ev);
    }
    final Set<EventInfo> overrides = new TreeSet<EventInfo>();
    if (cei.getOverrides() != null) {
        for (final CoreEventInfo ocei : cei.getOverrides()) {
            final BwEventProxy op = (BwEventProxy) ocei.getEvent();
            overrides.add(new EventInfo(op));
        }
    }
    final EventInfo ei = new EventInfo(ev, overrides);
    /* Reconstruct if any contained items. */
    if (cei.getNumContainedItems() > 0) {
        for (CoreEventInfo ccei : cei.getContainedItems()) {
            BwEvent cv = ccei.getEvent();
            ei.addContainedItem(new EventInfo(cv));
        }
    }
    ei.setCurrentAccess(cei.getCurrentAccess());
    return ei;
}
Also used : CoreEventInfo(org.bedework.calcorei.CoreEventInfo) EventInfo(org.bedework.calfacade.svc.EventInfo) BwEventAnnotation(org.bedework.calfacade.BwEventAnnotation) TreeSet(java.util.TreeSet) CoreEventInfo(org.bedework.calcorei.CoreEventInfo) BwEvent(org.bedework.calfacade.BwEvent) BwEventProxy(org.bedework.calfacade.BwEventProxy)

Example 7 with BwEventProxy

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

the class Events method add.

@Override
public UpdateResult add(final EventInfo ei, final boolean noInvites, final boolean schedulingInbox, final boolean autoCreateCollection, final boolean rollbackOnError) throws CalFacadeException {
    try {
        if (getPrincipalInfo().getSubscriptionsOnly()) {
            throw new CalFacadeForbidden("User has read only access");
        }
        final UpdateResult updResult = ei.getUpdResult();
        updResult.adding = true;
        updResult.hasChanged = true;
        final BwEvent event = ei.getEvent();
        adjustEntities(ei);
        final BwPreferences prefs = getSvc().getPrefsHandler().get();
        if (prefs != null) {
            final Collection<BwCategory> cats = getSvc().getCategoriesHandler().get(prefs.getDefaultCategoryUids());
            for (final BwCategory cat : cats) {
                event.addCategory(cat);
            }
        }
        final RealiasResult raResp = reAlias(event);
        if (raResp.getStatus() != ok) {
            throw new CalFacadeException(CalFacadeException.badRequest, "Status: " + raResp.getStatus() + " message: " + raResp.getMessage());
        }
        // Or just validate?
        assignGuid(event);
        updateEntities(updResult, event);
        BwCalendar cal = validate(event, true, schedulingInbox, autoCreateCollection);
        BwEventProxy proxy = null;
        BwEvent override = null;
        if (event instanceof BwEventProxy) {
            proxy = (BwEventProxy) event;
            override = proxy.getRef();
            setupSharableEntity(override, getPrincipal().getPrincipalRef());
        } else {
            setupSharableEntity(event, getPrincipal().getPrincipalRef());
            if (ei.getNumContainedItems() > 0) {
                for (final EventInfo aei : ei.getContainedItems()) {
                    final BwEvent av = aei.getEvent();
                    av.setParent(event);
                    setupSharableEntity(av, getPrincipal().getPrincipalRef());
                }
            }
        }
        final BwCalendar undereffedCal = cal;
        if (cal.getInternalAlias()) {
            /* Resolve the alias and put the event in it's proper place */
            // XXX This is probably OK for non-public admin
            final boolean setCats = getSvc().getPars().getPublicAdmin();
            if (!setCats) {
                cal = getCols().resolveAlias(cal, true, false);
            } else {
                while (true) {
                    final Set<BwCategory> cats = cal.getCategories();
                    for (final BwCategory cat : cats) {
                        event.addCategory(cat);
                    }
                    if (!cal.getInternalAlias()) {
                        break;
                    }
                    cal = getCols().resolveAlias(cal, false, false);
                }
            }
            event.setColPath(cal.getPath());
        }
        if (!cal.getCalendarCollection()) {
            throw new CalFacadeAccessException();
        }
        if (!event.getPublick() && Util.isEmpty(event.getAlarms())) {
            setDefaultAlarms(ei, undereffedCal);
        }
        boolean schedulingObject = false;
        if (cal.getCollectionInfo().scheduling && (event.getOrganizerSchedulingObject() || event.getAttendeeSchedulingObject())) {
            schedulingObject = true;
        }
        final Integer maxAttendees = getSvc().getAuthProperties().getMaxAttendeesPerInstance();
        if ((maxAttendees != null) && !Util.isEmpty(event.getAttendees()) && (event.getAttendees().size() > maxAttendees)) {
            throw new CalFacadeException(CalFacadeException.schedulingTooManyAttendees);
        }
        event.setDtstamps(getCurrentTimestamp());
        if (schedulingObject) {
            event.updateStag(getCurrentTimestamp());
        }
        /* All Overrides go in same calendar and have same name */
        final Collection<BwEventProxy> overrides = ei.getOverrideProxies();
        if (overrides != null) {
            for (final BwEventProxy ovei : overrides) {
                setScheduleState(ovei, true, schedulingInbox);
                if ((maxAttendees != null) && !Util.isEmpty(ovei.getAttendees()) && (ovei.getAttendees().size() > maxAttendees)) {
                    throw new CalFacadeException(CalFacadeException.schedulingTooManyAttendees);
                }
                ovei.setDtstamps(getCurrentTimestamp());
                if (cal.getCollectionInfo().scheduling && (ovei.getOrganizerSchedulingObject() || ovei.getAttendeeSchedulingObject())) {
                    schedulingObject = true;
                }
                if (schedulingObject) {
                    ovei.updateStag(getCurrentTimestamp());
                }
                final BwEventAnnotation ann = ovei.getRef();
                ann.setColPath(event.getColPath());
                ann.setName(event.getName());
            }
        }
        if (event.getOrganizerSchedulingObject()) {
            // Set RSVP on all attendees with PARTSTAT = NEEDS_ACTION
            for (final BwAttendee att : event.getAttendees()) {
                if (att.getPartstat() == IcalDefs.partstatValNeedsAction) {
                    att.setRsvp(true);
                }
            }
        }
        UpdateEventResult uer = getCal().addEvent(ei, schedulingInbox, rollbackOnError);
        if (ei.getNumContainedItems() > 0) {
            for (final EventInfo oei : ei.getContainedItems()) {
                oei.getEvent().setName(event.getName());
                final UpdateEventResult auer = getCal().addEvent(oei, schedulingInbox, rollbackOnError);
                if (auer.errorCode != null) {
                // ?
                }
            }
        }
        updResult.failedOverrides = uer.failedOverrides;
        if (!noInvites) {
            if (event.getAttendeeSchedulingObject()) {
                // Attendee replying?
                updResult.reply = true;
            }
            if (cal.getCollectionInfo().scheduling && schedulingObject) {
                final SchedulingIntf sched = (SchedulingIntf) getSvc().getScheduler();
                sched.implicitSchedule(ei, false);
            /* We assume we don't need to update again to set attendee status
           * Trying to do an update results in duplicate key errors.
           *
           * If it turns out the scgedule status is not getting persisted in the
           * calendar entry then we need to find a way to set just that value in
           * already persisted entity.
           */
            }
        }
        return updResult;
    } catch (final Throwable t) {
        if (debug) {
            error(t);
        }
        getSvc().rollbackTransaction();
        if (t instanceof CalFacadeException) {
            throw (CalFacadeException) t;
        }
        throw new CalFacadeException(t);
    }
}
Also used : BwPreferences(org.bedework.calfacade.svc.BwPreferences) CoreEventInfo(org.bedework.calcorei.CoreEventInfo) EventInfo(org.bedework.calfacade.svc.EventInfo) BwCategory(org.bedework.calfacade.BwCategory) CalFacadeForbidden(org.bedework.calfacade.exc.CalFacadeForbidden) BwEvent(org.bedework.calfacade.BwEvent) SchedulingIntf(org.bedework.calsvc.scheduling.SchedulingIntf) BwCalendar(org.bedework.calfacade.BwCalendar) BwEventProxy(org.bedework.calfacade.BwEventProxy) CalFacadeAccessException(org.bedework.calfacade.exc.CalFacadeAccessException) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) BwEventAnnotation(org.bedework.calfacade.BwEventAnnotation) BwAttendee(org.bedework.calfacade.BwAttendee) UpdateResult(org.bedework.calfacade.svc.EventInfo.UpdateResult) UpdateEventResult(org.bedework.calcorei.CoreEventsI.UpdateEventResult)

Example 8 with BwEventProxy

use of org.bedework.calfacade.BwEventProxy 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 9 with BwEventProxy

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

the class Events method makeInstance.

private EventInfo makeInstance(final EventInfo ei, final String recurrenceId) throws CalFacadeException {
    final BwEvent ev = ei.getEvent();
    if (!ev.getRecurring()) {
        return ei;
    }
    if (!Util.isEmpty(ei.getOverrides())) {
        for (final EventInfo oei : ei.getOverrides()) {
            if (oei.getEvent().getRecurrenceId().equals(recurrenceId)) {
                oei.setRetrievedEvent(ei);
                oei.setCurrentAccess(ei.getCurrentAccess());
                return oei;
            }
        }
    }
    /* Not in the overrides - generate an instance */
    final BwDateTime rstart;
    final boolean dateOnly = ev.getDtstart().getDateType();
    if (dateOnly) {
        rstart = BwDateTime.makeBwDateTime(true, recurrenceId.substring(0, 8), null);
    } else {
        final String stzid = ev.getDtstart().getTzid();
        DateTime dt = null;
        try {
            dt = new DateTime(recurrenceId);
        } catch (final ParseException pe) {
            throw new CalFacadeException(pe);
        }
        final DtStart ds = ev.getDtstart().makeDtStart();
        dt.setTimeZone(ds.getTimeZone());
        rstart = BwDateTime.makeBwDateTime(dt);
    }
    final BwDateTime rend = rstart.addDuration(BwDuration.makeDuration(ev.getDuration()));
    final BwEventAnnotation ann = new BwEventAnnotation();
    ann.setDtstart(rstart);
    ann.setDtend(rend);
    ann.setRecurrenceId(recurrenceId);
    ann.setOwnerHref(ev.getOwnerHref());
    // Call it an override
    ann.setOverride(true);
    ann.setTombstoned(false);
    ann.setName(ev.getName());
    ann.setUid(ev.getUid());
    ann.setTarget(ev);
    ann.setMaster(ev);
    BwEvent proxy = new BwEventProxy(ann);
    EventInfo oei = new EventInfo(proxy);
    oei.setCurrentAccess(ei.getCurrentAccess());
    oei.setRetrievedEvent(ei);
    return oei;
}
Also used : DtStart(net.fortuna.ical4j.model.property.DtStart) CoreEventInfo(org.bedework.calcorei.CoreEventInfo) EventInfo(org.bedework.calfacade.svc.EventInfo) BwDateTime(org.bedework.calfacade.BwDateTime) BwEventAnnotation(org.bedework.calfacade.BwEventAnnotation) BwEvent(org.bedework.calfacade.BwEvent) ParseException(java.text.ParseException) BwEventProxy(org.bedework.calfacade.BwEventProxy) DateTime(net.fortuna.ical4j.model.DateTime) BwDateTime(org.bedework.calfacade.BwDateTime) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException)

Example 10 with BwEventProxy

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

the class RestoreImpl method restoreEvent.

@Override
public void restoreEvent(final EventInfo ei) throws Throwable {
    try {
        startTransaction();
        final UpdateEventResult uer = getCal().addEvent(ei, // scheduling
        false, false);
        if (!uer.addedUpdated) {
            throw new CalFacadeException(uer.errorCode);
        }
        if (uer.failedOverrides != null) {
            error("Following overrides failed for event ");
            error(ei.getEvent().toString());
            for (final BwEventProxy proxy : uer.failedOverrides) {
                error(proxy.toString());
            }
        }
    } finally {
        endTransaction();
    }
}
Also used : BwEventProxy(org.bedework.calfacade.BwEventProxy) UpdateEventResult(org.bedework.calcorei.CoreEventsI.UpdateEventResult) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException)

Aggregations

BwEventProxy (org.bedework.calfacade.BwEventProxy)42 BwEvent (org.bedework.calfacade.BwEvent)33 EventInfo (org.bedework.calfacade.svc.EventInfo)24 BwEventAnnotation (org.bedework.calfacade.BwEventAnnotation)19 CalFacadeException (org.bedework.calfacade.exc.CalFacadeException)12 CoreEventInfo (org.bedework.calcorei.CoreEventInfo)11 BwDateTime (org.bedework.calfacade.BwDateTime)9 BwAttendee (org.bedework.calfacade.BwAttendee)7 BwCalendar (org.bedework.calfacade.BwCalendar)7 ArrayList (java.util.ArrayList)5 TreeSet (java.util.TreeSet)5 BwXproperty (org.bedework.calfacade.BwXproperty)5 Dur (net.fortuna.ical4j.model.Dur)4 BwRecurrenceInstance (org.bedework.calfacade.BwRecurrenceInstance)4 Collection (java.util.Collection)3 DateTime (net.fortuna.ical4j.model.DateTime)3 BwCategory (org.bedework.calfacade.BwCategory)3 BwContact (org.bedework.calfacade.BwContact)3 BwEventObj (org.bedework.calfacade.BwEventObj)3 BwString (org.bedework.calfacade.BwString)3