Search in sources :

Example 1 with FreeBusy

use of com.zimbra.cs.fb.FreeBusy in project zm-mailbox by Zimbra.

the class Appointment method checkAvailability.

private ConflictCheckResult checkAvailability(long now, Invite invite, int maxNumConflicts, int maxPctConflicts) throws ServiceException {
    long st, et;
    if (invite.isRecurrence()) {
        // Resource is getting invited to a recurring appointment.
        st = getStartTime();
        et = getEndTime();
    } else {
        // Resource is getting invited to a single instance.
        ParsedDateTime dtStart = invite.getStartTime();
        ParsedDateTime dtEnd = invite.getEffectiveEndTime();
        if (dtStart != null && dtEnd != null) {
            st = dtStart.getUtcTime();
            et = dtEnd.getUtcTime();
        } else {
            // Start time and/or end time can't be determined.  Give up.
            return null;
        }
    }
    // Ignore conflicts in the past.
    st = Math.max(st, now);
    if (et <= st)
        return null;
    OperationContext octxt = new OperationContext(getAccount());
    Collection<Instance> instances;
    if (invite.isRecurrence()) {
        instances = expandInstances(st, et, false);
    } else {
        instances = new ArrayList<Instance>(1);
        instances.add(Instance.fromInvite(getId(), invite));
    }
    if (instances == null || instances.isEmpty())
        return null;
    int maxByPct = maxPctConflicts * instances.size() / 100;
    int maxConflicts = Math.min(maxNumConflicts, maxByPct);
    List<Conflict> list = new ArrayList<Conflict>();
    int numConflicts = 0;
    boolean hasMoreConflicts = false;
    for (Instance inst : instances) {
        if (numConflicts > Math.max(maxConflicts, MIN_CONFLICT_LIST_SIZE - 1)) {
            hasMoreConflicts = true;
            break;
        }
        long start = inst.getStart();
        long end = inst.getEnd();
        // Run free/busy search of this user between instance start/end times.
        FreeBusy fb = getMailbox().getFreeBusy(octxt, start, end, this);
        String status = fb.getBusiest();
        if (Conflict.isBusy(status)) {
            list.add(new Conflict(inst, status, fb));
            numConflicts++;
        }
    }
    return new ConflictCheckResult(list, numConflicts > maxConflicts, hasMoreConflicts);
}
Also used : FreeBusy(com.zimbra.cs.fb.FreeBusy) FBInstance(com.zimbra.cs.fb.FreeBusy.FBInstance) ArrayList(java.util.ArrayList) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime)

Example 2 with FreeBusy

use of com.zimbra.cs.fb.FreeBusy in project zm-mailbox by Zimbra.

the class ScheduleOutbox method handleFreebusyRequest.

private void handleFreebusyRequest(DavContext ctxt, ZComponent vfreebusy, String originator, String rcpt, Element resp) throws DavException, ServiceException {
    ZProperty dtstartProp = vfreebusy.getProperty(ICalTok.DTSTART);
    ZProperty dtendProp = vfreebusy.getProperty(ICalTok.DTEND);
    ZProperty durationProp = vfreebusy.getProperty(ICalTok.DURATION);
    if (dtstartProp == null || dtendProp == null && durationProp == null)
        throw new DavException("missing dtstart or dtend/duration in the schedule request", HttpServletResponse.SC_BAD_REQUEST, null);
    long start, end;
    try {
        ParsedDateTime startTime = ParsedDateTime.parseUtcOnly(dtstartProp.getValue());
        start = startTime.getUtcTime();
        if (dtendProp != null) {
            end = ParsedDateTime.parseUtcOnly(dtendProp.getValue()).getUtcTime();
        } else {
            ParsedDuration dur = ParsedDuration.parse(durationProp.getValue());
            ParsedDateTime endTime = startTime.add(dur);
            end = endTime.getUtcTime();
        }
    } catch (ParseException pe) {
        throw new DavException("can't parse date", HttpServletResponse.SC_BAD_REQUEST, pe);
    }
    ZimbraLog.dav.debug("rcpt: " + rcpt + ", start: " + new Date(start) + ", end: " + new Date(end));
    FreeBusy fb = null;
    if (ctxt.isFreebusyEnabled()) {
        FreeBusyQuery fbQuery = new FreeBusyQuery(ctxt.getRequest(), ctxt.getAuthAccount(), start, end, null);
        fbQuery.addEmailAddress(getAddressFromPrincipalURL(rcpt), FreeBusyQuery.CALENDAR_FOLDER_ALL);
        java.util.Collection<FreeBusy> fbResult = fbQuery.getResults();
        if (fbResult.size() > 0)
            fb = fbResult.iterator().next();
    }
    if (fb != null) {
        String fbMsg = fb.toVCalendar(FreeBusy.Method.REPLY, originator, rcpt, null);
        resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
        resp.addElement(DavElements.E_REQUEST_STATUS).setText("2.0;Success");
        resp.addElement(DavElements.E_CALENDAR_DATA).setText(fbMsg);
    } else {
        resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
        resp.addElement(DavElements.E_REQUEST_STATUS).setText("5.3;No f/b for the user");
    }
}
Also used : FreeBusy(com.zimbra.cs.fb.FreeBusy) DavException(com.zimbra.cs.dav.DavException) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) FreeBusyQuery(com.zimbra.cs.fb.FreeBusyQuery) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ParseException(java.text.ParseException) Date(java.util.Date)

Example 3 with FreeBusy

use of com.zimbra.cs.fb.FreeBusy in project zm-mailbox by Zimbra.

the class CalendarCollection method getFreeBusyReport.

/* Returns iCalalendar (RFC 2445) representation of freebusy report for specified time range. */
public String getFreeBusyReport(DavContext ctxt, TimeRange range) throws ServiceException, DavException {
    Mailbox mbox = getCalendarMailbox(ctxt);
    FreeBusy fb = mbox.getFreeBusy(ctxt.getOperationContext(), range.getStart(), range.getEnd(), FreeBusyQuery.CALENDAR_FOLDER_ALL);
    return fb.toVCalendar(FreeBusy.Method.REPLY, ctxt.getAuthAccount().getName(), mbox.getAccount().getName(), null);
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) FreeBusy(com.zimbra.cs.fb.FreeBusy)

Example 4 with FreeBusy

use of com.zimbra.cs.fb.FreeBusy in project zm-mailbox by Zimbra.

the class PublicICalServlet method doGetFreeBusy.

/**
 * http://localhost:7070/service/pubcal/freebusy.ifb?acct=user@host.com
 *
 * @param req
 * @param resp
 * @throws IOException
 * @throws ServletException
 */
public final void doGetFreeBusy(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    String acctName = req.getParameter(QP_ACCOUNT);
    String startStr = req.getParameter(QP_START_TIME);
    String endStr = req.getParameter(QP_END_TIME);
    resp.setContentType(MimeConstants.CT_TEXT_CALENDAR);
    if (checkBlankOrNull(resp, QP_ACCOUNT, acctName))
        return;
    long now = new Date().getTime();
    long rangeStart = now - Constants.MILLIS_PER_WEEK;
    long rangeEnd = now + (2 * Constants.MILLIS_PER_MONTH);
    if (startStr != null)
        rangeStart = Long.parseLong(startStr);
    if (endStr != null)
        rangeEnd = Long.parseLong(endStr);
    if (rangeEnd < rangeStart) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "End time must be after Start time");
        return;
    }
    long days = (rangeEnd - rangeStart) / Constants.MILLIS_PER_DAY;
    long maxDays = LC.calendar_freebusy_max_days.longValueWithinRange(0, 36600);
    if (days > maxDays) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Requested range is too large (max " + maxDays + " days)");
        return;
    }
    String targetAccountId = null;
    try {
        Account targetAccount = Provisioning.getInstance().get(AccountBy.name, acctName);
        if (targetAccount != null)
            targetAccountId = targetAccount.getId();
    } catch (ServiceException e) {
    }
    AuthToken at = getAuthTokenFromCookie(req, resp, true);
    if (at == null) {
        String authTokenParam = req.getParameter(QP_AUTH_TOKEN);
        if (authTokenParam != null) {
            try {
                at = AuthProvider.getAuthToken(authTokenParam);
            } catch (AuthTokenException e) {
                sLog.warn("Auth error: " + e.getMessage(), e);
            }
        }
    }
    Account authAccount = null;
    ZimbraSoapContext zsc = null;
    if (at != null) {
        try {
            authAccount = Provisioning.getInstance().get(AccountBy.id, at.getAccountId(), at);
        } catch (ServiceException e) {
            sLog.warn("Auth error: " + e.getMessage(), e);
        }
        try {
            zsc = new ZimbraSoapContext(at, targetAccountId, SoapProtocol.SoapJS, SoapProtocol.SoapJS);
        } catch (ServiceException e) {
            sLog.error("Error initializing request context", e);
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error initializing request context");
            return;
        }
    } else {
        authAccount = GuestAccount.ANONYMOUS_ACCT;
    }
    FreeBusyQuery fbQuery = new FreeBusyQuery(req, zsc, authAccount, rangeStart, rangeEnd, null);
    fbQuery.addEmailAddress(acctName, FreeBusyQuery.CALENDAR_FOLDER_ALL);
    Collection<FreeBusy> result = fbQuery.getResults();
    FreeBusy fb = null;
    if (result.size() > 0)
        fb = result.iterator().next();
    else
        fb = FreeBusy.emptyFreeBusy(acctName, rangeStart, rangeEnd);
    String url = req.getRequestURL() + "?" + req.getQueryString();
    String fbMsg = fb.toVCalendar(FreeBusy.Method.PUBLISH, acctName, null, url);
    resp.getOutputStream().write(fbMsg.getBytes());
}
Also used : GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) ServiceException(com.zimbra.common.service.ServiceException) FreeBusy(com.zimbra.cs.fb.FreeBusy) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) AuthTokenException(com.zimbra.cs.account.AuthTokenException) FreeBusyQuery(com.zimbra.cs.fb.FreeBusyQuery) AuthToken(com.zimbra.cs.account.AuthToken) Date(java.util.Date)

Example 5 with FreeBusy

use of com.zimbra.cs.fb.FreeBusy in project zm-mailbox by Zimbra.

the class ToXML method encodeFreeBusy.

public static Element encodeFreeBusy(Element parent, FreeBusy fb) {
    Element resp = parent.addNonUniqueElement(MailConstants.E_FREEBUSY_USER);
    resp.addAttribute(MailConstants.A_ID, fb.getName());
    for (Iterator<FreeBusy.Interval> iter = fb.iterator(); iter.hasNext(); ) {
        FreeBusy.Interval cur = iter.next();
        String status = cur.getStatus();
        Element elt;
        if (status.equals(IcalXmlStrMap.FBTYPE_FREE)) {
            elt = resp.addNonUniqueElement(MailConstants.E_FREEBUSY_FREE);
        } else if (status.equals(IcalXmlStrMap.FBTYPE_BUSY)) {
            elt = resp.addNonUniqueElement(MailConstants.E_FREEBUSY_BUSY);
        } else if (status.equals(IcalXmlStrMap.FBTYPE_BUSY_TENTATIVE)) {
            elt = resp.addNonUniqueElement(MailConstants.E_FREEBUSY_BUSY_TENTATIVE);
        } else if (status.equals(IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE)) {
            elt = resp.addNonUniqueElement(MailConstants.E_FREEBUSY_BUSY_UNAVAILABLE);
        } else if (status.equals(IcalXmlStrMap.FBTYPE_NODATA)) {
            elt = resp.addNonUniqueElement(MailConstants.E_FREEBUSY_NODATA);
        } else {
            assert (false);
            elt = null;
        }
        if (elt != null) {
            elt.addAttribute(MailConstants.A_CAL_START_TIME, cur.getStart());
            elt.addAttribute(MailConstants.A_CAL_END_TIME, cur.getEnd());
            if (cur.isDetailsExist()) {
                elt.addAttribute(MailConstants.E_CAL_EVENT_ID, cur.getId());
                elt.addAttribute(MailConstants.E_CAL_EVENT_SUBJECT, cur.getSubject());
                elt.addAttribute(MailConstants.E_CAL_EVENT_LOCATION, cur.getLocation());
                elt.addAttribute(MailConstants.E_CAL_EVENT_ISMEETING, cur.isMeeting());
                elt.addAttribute(MailConstants.E_CAL_EVENT_ISPRIVATE, cur.isPrivate());
                elt.addAttribute(MailConstants.E_CAL_EVENT_ISRECURRING, cur.isRecurring());
                elt.addAttribute(MailConstants.E_CAL_EVENT_ISREMINDERSET, cur.isReminderSet());
                elt.addAttribute(MailConstants.E_CAL_EVENT_ISEXCEPTION, cur.isException());
            }
            if (!cur.isHasPermission()) {
                elt.addAttribute(MailConstants.E_CAL_EVENT_HASPERMISSION, cur.isHasPermission());
            }
        }
    }
    return resp;
}
Also used : FreeBusy(com.zimbra.cs.fb.FreeBusy) Element(com.zimbra.common.soap.Element)

Aggregations

FreeBusy (com.zimbra.cs.fb.FreeBusy)9 Element (com.zimbra.common.soap.Element)3 Account (com.zimbra.cs.account.Account)3 FreeBusyQuery (com.zimbra.cs.fb.FreeBusyQuery)3 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)3 ArrayList (java.util.ArrayList)3 Date (java.util.Date)3 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)2 FBInstance (com.zimbra.cs.fb.FreeBusy.FBInstance)2 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)1 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)1 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)1 ServiceException (com.zimbra.common.service.ServiceException)1 AuthToken (com.zimbra.cs.account.AuthToken)1 AuthTokenException (com.zimbra.cs.account.AuthTokenException)1 GuestAccount (com.zimbra.cs.account.GuestAccount)1 Provisioning (com.zimbra.cs.account.Provisioning)1 DavException (com.zimbra.cs.dav.DavException)1 Interval (com.zimbra.cs.fb.FreeBusy.Interval)1 Appointment (com.zimbra.cs.mailbox.Appointment)1