use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class RemoveAttachments method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
Element msgElem = request.getElement(MailConstants.E_MSG);
ItemId iid = new ItemId(msgElem.getAttribute(MailConstants.A_ID), zsc);
Collection<String> parts = sortPartIds(msgElem.getAttribute(MailConstants.A_PART));
Message msg = mbox.getMessageById(octxt, iid.getId());
InputStream is = null;
try {
MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession(), is = StoreManager.getInstance().getContent(msg.getBlob().getLocalBlob()));
// do not allow removing attachments of encrypted/pkcs7-signed messages
if (Mime.isEncrypted(mm.getContentType()) || Mime.isPKCS7Signed(mm.getContentType())) {
throw ServiceException.OPERATION_DENIED("not allowed to remove attachments of encrypted/pkcs7-signed message");
}
for (String part : parts) stripPart(mm, part);
mm.saveChanges();
ParsedMessage pm = new ParsedMessage(mm, msg.getDate(), mbox.attachmentsIndexingEnabled());
msg = removeAttachmentOperation(mbox, octxt, pm, msg);
} catch (IOException ioe) {
throw ServiceException.FAILURE("error reading existing message blob", ioe);
} catch (MessagingException me) {
throw ServiceException.FAILURE("error reading existing message blob", me);
} finally {
ByteUtil.closeStream(is);
}
Element response = zsc.createElement(MailConstants.REMOVE_ATTACHMENTS_RESPONSE);
// FIXME: inefficient -- this recalculates the MimeMessage (but RemoveAttachments is called rarely)
ToXML.encodeMessageAsMP(response, ifmt, octxt, msg, null, -1, true, true, null, true, false, LC.mime_encode_missing_blob.booleanValue());
return response;
}
use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class SaveDraft method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
Element msgElem = request.getElement(MailConstants.E_MSG);
int id = (int) msgElem.getAttributeLong(MailConstants.A_ID, Mailbox.ID_AUTO_INCREMENT);
String originalId = msgElem.getAttribute(MailConstants.A_ORIG_ID, null);
ItemId iidOrigid = originalId == null ? null : new ItemId(originalId, zsc);
String replyType = msgElem.getAttribute(MailConstants.A_REPLY_TYPE, null);
String identity = msgElem.getAttribute(MailConstants.A_IDENTITY_ID, null);
String account = msgElem.getAttribute(MailConstants.A_FOR_ACCOUNT, null);
// allow the caller to update the draft's metadata at the same time as they save the draft
String folderId = msgElem.getAttribute(MailConstants.A_FOLDER, null);
ItemId iidFolder = new ItemId(folderId == null ? "-1" : folderId, zsc);
if (!iidFolder.belongsTo(mbox)) {
throw ServiceException.INVALID_REQUEST("cannot move item between mailboxes", null);
} else if (folderId != null && iidFolder.getId() <= 0) {
throw MailServiceException.NO_SUCH_FOLDER(iidFolder.getId());
}
String flags = msgElem.getAttribute(MailConstants.A_FLAGS, null);
String[] tags = TagUtil.parseTags(msgElem, mbox, octxt);
Color color = ItemAction.getColor(msgElem);
// check to see whether the entire message has been uploaded under separate cover
String attachment = msgElem.getAttribute(MailConstants.A_ATTACHMENT_ID, null);
long autoSendTime = new Long(msgElem.getAttribute(MailConstants.A_AUTO_SEND_TIME, "0"));
ParseMimeMessage.MimeMessageData mimeData = new ParseMimeMessage.MimeMessageData();
Message msg;
try {
MimeMessage mm;
if (attachment != null) {
mm = SendMsg.parseUploadedMessage(zsc, attachment, mimeData);
} else {
mm = ParseMimeMessage.parseMimeMsgSoap(zsc, octxt, mbox, msgElem, null, mimeData, true);
}
long date = System.currentTimeMillis();
try {
Date d = new Date();
mm.setSentDate(d);
date = d.getTime();
} catch (Exception ignored) {
}
try {
mm.saveChanges();
} catch (MessagingException me) {
throw ServiceException.FAILURE("completing MIME message object", me);
}
ParsedMessage pm = new ParsedMessage(mm, date, mbox.attachmentsIndexingEnabled());
if (autoSendTime != 0) {
AccountUtil.checkQuotaWhenSendMail(mbox);
}
String origid = iidOrigid == null ? null : iidOrigid.toString(account == null ? mbox.getAccountId() : account);
msg = mbox.saveDraft(octxt, pm, id, origid, replyType, identity, account, autoSendTime);
} catch (IOException e) {
throw ServiceException.FAILURE("IOException while saving draft", e);
} finally {
// purge the messages fetched from other servers.
if (mimeData.fetches != null) {
FileUploadServlet.deleteUploads(mimeData.fetches);
}
}
// we can now purge the uploaded attachments
if (mimeData.uploads != null) {
FileUploadServlet.deleteUploads(mimeData.uploads);
}
// try to set the metadata on the new/revised draft
if (folderId != null || flags != null || !ArrayUtil.isEmpty(tags) || color != null) {
try {
// best not to fail if there's an error here...
ItemActionHelper.UPDATE(octxt, mbox, zsc.getResponseProtocol(), Arrays.asList(msg.getId()), MailItem.Type.MESSAGE, null, null, iidFolder, flags, tags, color);
// and make sure the Message object reflects post-update reality
msg = mbox.getMessageById(octxt, msg.getId());
} catch (ServiceException e) {
ZimbraLog.soap.warn("error setting metadata for draft " + msg.getId() + "; skipping that operation", e);
}
}
if (schedulesAutoSendTask()) {
if (id != Mailbox.ID_AUTO_INCREMENT) {
// Cancel any existing auto-send task for this draft
AutoSendDraftTask.cancelTask(id, mbox.getId());
}
if (autoSendTime != 0) {
// schedule a new auto-send-draft task
AutoSendDraftTask.scheduleTask(msg.getId(), mbox.getId(), autoSendTime);
}
}
return generateResponse(zsc, ifmt, octxt, mbox, msg);
}
use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class Search method runSimpleAppointmentQuery.
private static void runSimpleAppointmentQuery(Element parent, SearchParams params, OperationContext octxt, ZimbraSoapContext zsc, Account authAcct, Mailbox mbox, List<String> folderIdStrs) throws ServiceException {
Set<MailItem.Type> types = params.getTypes();
MailItem.Type type = types.size() == 1 ? Iterables.getOnlyElement(types) : MailItem.Type.APPOINTMENT;
if (params.getSortBy() != null) {
parent.addAttribute(MailConstants.A_SORTBY, params.getSortBy().toString());
}
parent.addAttribute(MailConstants.A_QUERY_OFFSET, params.getOffset());
parent.addAttribute(MailConstants.A_QUERY_MORE, false);
List<ItemId> folderIids = new ArrayList<ItemId>(folderIdStrs.size());
for (String folderIdStr : folderIdStrs) {
folderIids.add(new ItemId(folderIdStr, zsc));
}
Provisioning prov = Provisioning.getInstance();
MailboxManager mboxMgr = MailboxManager.getInstance();
Server localServer = prov.getLocalServer();
Map<Server, Map<String, List<Integer>>> /* folder ids */
groupedByServer = groupByServer(ItemId.groupFoldersByAccount(octxt, mbox, folderIids));
// Look up in calendar cache first.
if (LC.calendar_cache_enabled.booleanValue()) {
CalSummaryCache calCache = CalendarCacheManager.getInstance().getSummaryCache();
long rangeStart = params.getCalItemExpandStart();
long rangeEnd = params.getCalItemExpandEnd();
for (Iterator<Map.Entry<Server, Map<String, List<Integer>>>> serverIter = groupedByServer.entrySet().iterator(); serverIter.hasNext(); ) {
Map.Entry<Server, Map<String, List<Integer>>> serverMapEntry = serverIter.next();
Map<String, List<Integer>> accountFolders = serverMapEntry.getValue();
// for each account
for (Iterator<Map.Entry<String, List<Integer>>> acctIter = accountFolders.entrySet().iterator(); acctIter.hasNext(); ) {
Map.Entry<String, List<Integer>> acctEntry = acctIter.next();
String acctId = acctEntry.getKey();
List<Integer> folderIds = acctEntry.getValue();
// Setup ItemIdFormatter appropriate for this folder which might not be in the authed account
// but also take note of presense of <noqualify/> in SOAP context
ItemIdFormatter ifmt = new ItemIdFormatter(authAcct.getId(), acctId, zsc.wantsUnqualifiedIds());
// for each folder
for (Iterator<Integer> iterFolderId = folderIds.iterator(); iterFolderId.hasNext(); ) {
int folderId = iterFolderId.next();
try {
CalendarDataResult result = calCache.getCalendarSummary(octxt, acctId, folderId, type, rangeStart, rangeEnd, true);
if (result != null) {
// Found data in cache.
iterFolderId.remove();
addCalendarDataToResponse(parent, zsc, ifmt, result.data, result.allowPrivateAccess);
}
} catch (ServiceException e) {
String ecode = e.getCode();
if (ecode.equals(ServiceException.PERM_DENIED)) {
// share permission was revoked
ZimbraLog.calendar.warn("Ignoring permission error during calendar search of folder %s", ifmt.formatItemId(folderId), e);
} else if (ecode.equals(MailServiceException.NO_SUCH_FOLDER)) {
// shared calendar folder was deleted by the owner
ZimbraLog.calendar.warn("Ignoring deleted calendar folder %s", ifmt.formatItemId(folderId));
} else {
throw e;
}
iterFolderId.remove();
}
}
if (folderIds.isEmpty())
acctIter.remove();
}
if (accountFolders.isEmpty())
serverIter.remove();
}
}
// For any remaining calendars, we have to get the data the hard way.
for (Map.Entry<Server, Map<String, List<Integer>>> serverMapEntry : groupedByServer.entrySet()) {
Server server = serverMapEntry.getKey();
Map<String, List<Integer>> accountFolders = serverMapEntry.getValue();
if (server.equals(localServer)) {
// local server
for (Map.Entry<String, List<Integer>> entry : accountFolders.entrySet()) {
String acctId = entry.getKey();
List<Integer> folderIds = entry.getValue();
if (folderIds.isEmpty())
continue;
Account targetAcct = prov.get(AccountBy.id, acctId);
if (targetAcct == null) {
ZimbraLog.calendar.warn("Skipping unknown account " + acctId + " during calendar search");
continue;
}
Mailbox targetMbox = mboxMgr.getMailboxByAccount(targetAcct);
searchLocalAccountCalendars(parent, params, octxt, zsc, authAcct, targetMbox, folderIds, type);
}
} else {
// remote server
searchRemoteAccountCalendars(parent, params, zsc, authAcct, accountFolders);
}
}
}
use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class Search method searchLocalAccountCalendars.
private static void searchLocalAccountCalendars(Element parent, SearchParams params, OperationContext octxt, ZimbraSoapContext zsc, Account authAcct, Mailbox targetMbox, List<Integer> folderIds, MailItem.Type type) throws ServiceException {
ItemIdFormatter ifmt = new ItemIdFormatter(authAcct.getId(), targetMbox.getAccountId(), false);
long rangeStart = params.getCalItemExpandStart();
long rangeEnd = params.getCalItemExpandEnd();
for (int folderId : folderIds) {
try {
CalendarDataResult result = targetMbox.getCalendarSummaryForRange(octxt, folderId, type, rangeStart, rangeEnd);
if (result != null) {
addCalendarDataToResponse(parent, zsc, ifmt, result.data, result.allowPrivateAccess);
}
} catch (ServiceException e) {
String ecode = e.getCode();
if (ecode.equals(ServiceException.PERM_DENIED)) {
// share permission was revoked
ZimbraLog.calendar.warn("Ignoring permission error during calendar search of folder " + ifmt.formatItemId(folderId), e);
} else if (ecode.equals(MailServiceException.NO_SUCH_FOLDER)) {
// shared calendar folder was deleted by the owner
ZimbraLog.calendar.warn("Ignoring deleted calendar folder " + ifmt.formatItemId(folderId));
} else {
throw e;
}
}
}
}
use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class SendInviteReply method remoteSendInviteReply.
private static void remoteSendInviteReply(ZMailbox zmbx, Element origRequest, AddInviteResult ids) throws ServiceException {
ItemIdFormatter ifmt = new ItemIdFormatter();
Element req = origRequest.clone();
req.detach();
String idStr = ifmt.formatItemId(ids.getCalItemId(), ids.getInvId());
req.addAttribute(MailConstants.A_ID, idStr);
req.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, ids.getCompNum());
zmbx.invoke(req);
}
Aggregations