use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.
the class CalendarUtils method parseInviteForCounter.
static ParseMimeMessage.InviteParserResult parseInviteForCounter(Account account, Invite oldInvite, MailItem.Type type, Element inviteElem) throws ServiceException {
TimeZoneMap tzMap = new TimeZoneMap(Util.getAccountTimeZone(account));
Invite inv = new Invite(ICalTok.COUNTER.toString(), tzMap, false);
CalendarUtils.parseInviteElementCommon(account, type, inviteElem, inv, true, true);
// Get the existing invite to populate X-MS-OLK-ORIGINALSTART and X-MS-OLK-ORIGINALEND
if (oldInvite == null) {
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
CalendarItem calItem = mbox.getCalendarItemByUid(null, inv.getUid());
if (calItem != null)
oldInvite = calItem.getInvite(inv.getRecurId());
}
if (oldInvite != null) {
// Add TZIDs from oldInvite to inv
inv.getTimeZoneMap().add(oldInvite.getTimeZoneMap());
// Add ORIGINALSTART x-prop
ParsedDateTime dt = oldInvite.getStartTime();
if (dt != null) {
ZCalendar.ZProperty prop = new ZCalendar.ZProperty("X-MS-OLK-ORIGINALSTART");
prop.setValue(dt.getDateTimePartString());
if (dt.getTZName() != null)
prop.addParameter(new ZParameter(ICalTok.TZID, dt.getTZName()));
inv.addXProp(prop);
}
// Add ORIGINALEND x-prop
dt = oldInvite.getEffectiveEndTime();
if (dt != null) {
ZCalendar.ZProperty prop = new ZCalendar.ZProperty("X-MS-OLK-ORIGINALEND");
prop.setValue(dt.getDateTimePartString());
if (dt.getTZName() != null)
prop.addParameter(new ZParameter(ICalTok.TZID, dt.getTZName()));
inv.addXProp(prop);
}
// Add LOCATION if not already exist.
if (inv.getLocation() == null || inv.getLocation().isEmpty())
inv.setLocation(oldInvite.getLocation());
}
// UID
String uid = inv.getUid();
if (uid == null || uid.length() == 0)
throw ServiceException.INVALID_REQUEST("Missing uid in a counter invite", null);
// ORGANIZER
if (!inv.hasOrganizer())
throw ServiceException.INVALID_REQUEST("Missing organizer in a counter invite", null);
// DTSTAMP
if (inv.getDTStamp() == 0) {
// zdsync
inv.setDtStamp(new Date().getTime());
}
// DTSTART
if (inv.getStartTime() == null)
throw ServiceException.INVALID_REQUEST("Missing dtstart in a counter invite", null);
// iCalendar object doesn't have an ATTENDEE property. RFC2446 doesn't require one.
if (!inv.hasOtherAttendees()) {
ZAttendee at = new ZAttendee(account.getMail());
at.setPartStat(IcalXmlStrMap.PARTSTAT_TENTATIVE);
inv.addAttendee(at);
}
inv.setLocalOnly(false);
ZVCalendar iCal = inv.newToICalendar(true);
String summaryStr = inv.getName() != null ? inv.getName() : "";
ParseMimeMessage.InviteParserResult toRet = new ParseMimeMessage.InviteParserResult();
toRet.mCal = iCal;
toRet.mUid = inv.getUid();
toRet.mSummary = summaryStr;
toRet.mInvite = inv;
return toRet;
}
use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.
the class CancelCalendarItem method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Account acct = getRequestedAccount(zsc);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemId iid = new ItemId(request.getAttribute(MailConstants.A_ID), zsc);
if (!iid.hasSubpart())
throw ServiceException.INVALID_REQUEST("missing invId subpart: id should be specified as \"item-inv\"", null);
int compNum = (int) request.getAttributeLong(MailConstants.E_INVITE_COMPONENT);
CalendarItem calItem = mbox.getCalendarItemById(octxt, iid.getId());
if (calItem == null)
throw MailServiceException.NO_SUCH_CALITEM(iid.getId(), " for CancelCalendarItemRequest(" + iid + "," + compNum + ")");
if (calItem.inTrash())
throw ServiceException.INVALID_REQUEST("cannot cancel a calendar item under trash", null);
// We probably don't want to bother with conflict check for a cancel request...
Invite inv = calItem.getInvite(iid.getSubpartId(), compNum);
if (inv == null)
throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
MailSendQueue sendQueue = new MailSendQueue();
try {
Element recurElt = request.getOptionalElement(MailConstants.E_INSTANCE);
if (recurElt != null) {
TimeZoneMap tzmap = inv.getTimeZoneMap();
Element tzElem = request.getOptionalElement(MailConstants.E_CAL_TZ);
ICalTimeZone tz = null;
if (tzElem != null) {
tz = CalendarUtils.parseTzElement(tzElem);
tzmap.add(tz);
}
RecurId recurId = CalendarUtils.parseRecurId(recurElt, tzmap);
// trace logging
ZimbraLog.calendar.info("<CancelCalendarItem> id=%d, folderId=%d, subject=\"%s\", UID=%s, recurId=%s", calItem.getId(), calItem.getFolderId(), inv.isPublic() ? inv.getName() : "(private)", calItem.getUid(), recurId.getDtZ());
Element msgElem = request.getOptionalElement(MailConstants.E_MSG);
cancelInstance(zsc, octxt, msgElem, acct, mbox, calItem, inv, recurId, inv.getAttendees(), sendQueue);
} else {
// if recur is not set, then we're canceling the entire calendar item...
// trace logging
ZimbraLog.calendar.info("<CancelCalendarItem> id=%d, folderId=%d, subject=\"%s\", UID=%s", calItem.getId(), calItem.getFolderId(), inv.isPublic() ? inv.getName() : "(private)", calItem.getUid());
Invite seriesInv = calItem.getDefaultInviteOrNull();
if (seriesInv != null) {
if (seriesInv.getMethod().equals(ICalTok.REQUEST.toString()) || seriesInv.getMethod().equals(ICalTok.PUBLISH.toString())) {
if (seriesInv.isOrganizer()) {
// Send cancel notice to attendees who were invited to exception instances only.
// These attendees need to be notified separately because they aren't included in the series
// cancel notice.
List<ZAttendee> atsSeries = seriesInv.getAttendees();
Invite[] invs = calItem.getInvites();
long now = octxt != null ? octxt.getTimestamp() : System.currentTimeMillis();
for (Invite exceptInv : invs) {
if (exceptInv != seriesInv) {
String mthd = exceptInv.getMethod();
if ((mthd.equals(ICalTok.REQUEST.toString()) || mthd.equals(ICalTok.PUBLISH.toString())) && inviteIsAfterTime(exceptInv, now)) {
List<ZAttendee> atsExcept = exceptInv.getAttendees();
// Find exception instance attendees who aren't series attendees.
List<ZAttendee> ats = CalendarUtils.getRemovedAttendees(atsExcept, atsSeries, false, acct);
if (!ats.isEmpty()) {
// notify ats
cancelInstance(zsc, octxt, null, acct, mbox, calItem, exceptInv, exceptInv.getRecurId(), ats, sendQueue);
}
}
}
}
}
// Finally, cancel the series.
Element msgElem = request.getOptionalElement(MailConstants.E_MSG);
cancelInvite(zsc, octxt, msgElem, acct, mbox, calItem, seriesInv, sendQueue);
}
// disable change constraint checking since we've just successfully done a modify
octxt = new OperationContext(octxt).unsetChangeConstraint();
}
}
} finally {
sendQueue.send();
}
Element response = getResponseElement(zsc);
return response;
}
use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.
the class AnnounceOrganizerChange method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Account acct = getRequestedAccount(zsc);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemId iid = new ItemId(request.getAttribute(MailConstants.A_ID), zsc);
MailSendQueue sendQueue = new MailSendQueue();
Element response = getResponseElement(zsc);
mbox.lock.lock();
try {
CalendarItem calItem = mbox.getCalendarItemById(octxt, iid.getId());
sendOrganizerChangeMessage(zsc, octxt, calItem, acct, mbox, sendQueue);
} finally {
mbox.lock.release();
sendQueue.send();
}
return response;
}
use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.
the class DismissCalendarItemAlarm method handle.
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
String acctId = mbox.getAccountId();
Account authAcct = getAuthenticatedAccount(zsc);
OperationContext octxt = getOperationContext(zsc, context);
Element response = getResponseElement(zsc);
for (String calItemElement : sCalItemElems) {
for (Iterator<Element> iter = request.elementIterator(calItemElement); iter.hasNext(); ) {
Element calItemElem = iter.next();
ItemId iid = new ItemId(calItemElem.getAttribute(MailConstants.A_ID), zsc);
long dismissedAt = calItemElem.getAttributeLong(MailConstants.A_CAL_ALARM_DISMISSED_AT);
// trace logging
ZimbraLog.calendar.info("<DismissCalendarItemAlarm> id=%s, at=%d", iid.toString(), dismissedAt);
// mailbox for this calendar item; not necessarily same as requested mailbox
Mailbox ciMbox = null;
String ciAcctId = iid.getAccountId();
if (ciAcctId == null || ciAcctId.equals(acctId)) {
ciMbox = mbox;
} else {
// Let's see if the account is a Desktop account.
if (AccountUtil.isZDesktopLocalAccount(zsc.getAuthtokenAccountId()))
ciMbox = MailboxManager.getInstance().getMailboxByAccountId(ciAcctId, false);
if (ciMbox == null)
throw MailServiceException.PERM_DENIED("cannot dismiss alarms of a shared calendar");
}
int calItemId = iid.getId();
ItemIdFormatter ifmt = new ItemIdFormatter(authAcct.getId(), acctId, false);
try {
ciMbox.dismissCalendarItemAlarm(octxt, calItemId, dismissedAt);
CalendarItem calItem = ciMbox.getCalendarItemById(octxt, calItemId);
Element calItemRespElem;
if (calItem instanceof Appointment)
calItemRespElem = response.addElement(MailConstants.E_APPOINTMENT);
else
calItemRespElem = response.addElement(MailConstants.E_TASK);
calItemRespElem.addAttribute(MailConstants.A_CAL_ID, iid.toString(ifmt));
boolean hidePrivate = !calItem.allowPrivateAccess(authAcct, zsc.isUsingAdminPrivileges());
boolean showAll = !hidePrivate || calItem.isPublic();
if (showAll) {
AlarmData alarmData = calItem.getAlarmData();
if (alarmData != null)
ToXML.encodeAlarmData(calItemRespElem, calItem, alarmData);
}
} catch (NoSuchItemException nsie) {
// item must not exist in db anymore.
// this can happen if an alarm is dismissed while a big sync is happening which deletes the item (e.g. bug 48560)
// since item is not in db, it has effectively been dismissed; return ok and no further alarms
Element calItemRespElem = response.addElement(calItemElement);
calItemRespElem.addAttribute(MailConstants.A_CAL_ID, iid.toString(ifmt));
}
}
}
return response;
}
use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.
the class RssFormatter method formatCallback.
@Override
public void formatCallback(UserServletContext context) throws IOException, ServiceException {
// ZimbraLog.mailbox.info("start = "+new Date(context.getStartTime()));
// ZimbraLog.mailbox.info("end = "+new Date(context.getEndTime()));
Iterator<? extends MailItem> iterator = null;
StringBuffer sb = new StringBuffer();
Element.XMLElement rss = new Element.XMLElement("rss");
int offset = context.getOffset();
int limit = context.getLimit();
try {
iterator = getMailItems(context, context.getStartTime(), context.getEndTime(), limit - offset);
context.resp.setCharacterEncoding("UTF-8");
context.resp.setContentType("application/rss+xml");
sb.append("<?xml version=\"1.0\"?>\n");
rss.addAttribute("version", "2.0");
Element channel = rss.addElement("channel");
channel.addElement("title").setText("Zimbra " + context.itemPath);
channel.addElement("link").setText("http://www.zimbra.com");
channel.addElement("description").setText("Zimbra item " + context.itemPath + " in RSS format.");
channel.addElement("generator").setText("Zimbra RSS Feed Servlet");
// channel.addElement("description").setText(query);
// MailDateFormat mdf = new MailDateFormat();
int curHit = 0;
while (iterator.hasNext()) {
MailItem itItem = iterator.next();
curHit++;
if (curHit > limit)
break;
if (curHit >= offset) {
if (itItem instanceof CalendarItem) {
// Don't return private appointments/tasks if the requester is not the mailbox owner.
CalendarItem calItem = (CalendarItem) itItem;
if (calItem.isPublic() || calItem.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges())) {
addCalendarItem(calItem, channel, context);
}
} else if (itItem instanceof Message) {
addMessage((Message) itItem, channel);
} else if (itItem instanceof Document) {
addDocument((Document) itItem, channel, context);
}
}
}
} finally {
if (iterator instanceof QueryResultIterator)
((QueryResultIterator) iterator).finished();
}
sb.append(rss.toString());
context.resp.getOutputStream().write(sb.toString().getBytes("UTF-8"));
}
Aggregations