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);
}
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");
}
}
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);
}
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());
}
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;
}
Aggregations