use of com.zimbra.cs.mailbox.DeliveryOptions in project zm-mailbox by Zimbra.
the class ZimbraLmtpBackend method deliverMessageToLocalMailboxes.
private void deliverMessageToLocalMailboxes(Blob blob, BlobInputStream bis, byte[] data, MimeMessage mm, LmtpEnvelope env) throws ServiceException, IOException {
List<LmtpAddress> recipients = env.getLocalRecipients();
String envSender = env.getSender().getEmailAddress();
boolean shared = recipients.size() > 1;
List<Integer> targetMailboxIds = new ArrayList<Integer>(recipients.size());
Map<LmtpAddress, RecipientDetail> rcptMap = new HashMap<LmtpAddress, RecipientDetail>(recipients.size());
try {
// Examine attachments indexing option for all recipients and
// prepare ParsedMessage versions needed. Parsing is done before
// attempting delivery to any recipient. Therefore, parse error
// will result in non-delivery to all recipients.
// ParsedMessage for users with attachments indexing
ParsedMessage pmAttachIndex = null;
// ParsedMessage for users without attachments indexing
ParsedMessage pmNoAttachIndex = null;
// message id for logging
String msgId = null;
for (LmtpAddress recipient : recipients) {
String rcptEmail = recipient.getEmailAddress();
Account account;
Mailbox mbox;
boolean attachmentsIndexingEnabled;
try {
account = Provisioning.getInstance().get(AccountBy.name, rcptEmail);
if (account == null) {
ZimbraLog.mailbox.warn("No account found delivering mail to " + rcptEmail);
continue;
}
mbox = MailboxManager.getInstance().getMailboxByAccount(account);
if (mbox == null) {
ZimbraLog.mailbox.warn("No mailbox found delivering mail to " + rcptEmail);
continue;
}
attachmentsIndexingEnabled = mbox.attachmentsIndexingEnabled();
} catch (ServiceException se) {
if (se.isReceiversFault()) {
ZimbraLog.mailbox.info("Recoverable exception getting mailbox for " + rcptEmail, se);
rcptMap.put(recipient, new RecipientDetail(null, null, null, false, DeliveryAction.defer));
} else {
ZimbraLog.mailbox.warn("Unrecoverable exception getting mailbox for " + rcptEmail, se);
}
continue;
}
if (account != null && mbox != null) {
ParsedMessageOptions pmo;
if (mm != null) {
pmo = new ParsedMessageOptions().setContent(mm).setDigest(blob.getDigest()).setSize(blob.getRawSize());
} else {
pmo = new ParsedMessageOptions(blob, data);
}
ParsedMessage pm;
if (attachmentsIndexingEnabled) {
if (pmAttachIndex == null) {
pmo.setAttachmentIndexing(true);
ZimbraLog.lmtp.debug("Creating ParsedMessage from %s with attachment indexing enabled", data == null ? "file" : "memory");
pmAttachIndex = new ParsedMessage(pmo);
}
pm = pmAttachIndex;
} else {
if (pmNoAttachIndex == null) {
pmo.setAttachmentIndexing(false);
ZimbraLog.lmtp.debug("Creating ParsedMessage from %s with attachment indexing disabled", data == null ? "file" : "memory");
pmNoAttachIndex = new ParsedMessage(pmo);
}
pm = pmNoAttachIndex;
}
msgId = pm.getMessageID();
if (account.isPrefMailLocalDeliveryDisabled()) {
ZimbraLog.lmtp.debug("Local delivery disabled for account %s", rcptEmail);
rcptMap.put(recipient, new RecipientDetail(account, mbox, pm, false, DeliveryAction.discard));
continue;
}
// For non-shared delivery (i.e. only one recipient),
// always deliver regardless of backup mode.
DeliveryAction da = DeliveryAction.deliver;
boolean endSharedDelivery = false;
if (shared) {
if (mbox.beginSharedDelivery()) {
endSharedDelivery = true;
} else {
// Skip delivery to mailboxes in backup mode.
da = DeliveryAction.defer;
}
}
rcptMap.put(recipient, new RecipientDetail(account, mbox, pm, endSharedDelivery, da));
if (da == DeliveryAction.deliver) {
targetMailboxIds.add(mbox.getId());
}
}
}
ZimbraLog.removeAccountFromContext();
if (ZimbraLog.lmtp.isInfoEnabled()) {
ZimbraLog.lmtp.info("Delivering message: size=%s, nrcpts=%d, sender=%s, msgid=%s", env.getSize() == 0 ? "unspecified" : Integer.toString(env.getSize()) + " bytes", recipients.size(), env.getSender(), msgId == null ? "" : msgId);
}
DeliveryContext sharedDeliveryCtxt = new DeliveryContext(shared, targetMailboxIds);
sharedDeliveryCtxt.setIncomingBlob(blob);
// version each recipient needs. Deliver!
for (LmtpAddress recipient : recipients) {
String rcptEmail = recipient.getEmailAddress();
LmtpReply reply = LmtpReply.TEMPORARY_FAILURE;
RecipientDetail rd = rcptMap.get(recipient);
if (rd.account != null)
ZimbraLog.addAccountNameToContext(rd.account.getName());
if (rd.mbox != null)
ZimbraLog.addMboxToContext(rd.mbox.getId());
boolean success = false;
try {
if (rd != null) {
switch(rd.action) {
case discard:
ZimbraLog.lmtp.info("accepted and discarded message from=%s,to=%s: local delivery is disabled", envSender, rcptEmail);
if (rd.account.getPrefMailForwardingAddress() != null) {
// mail forwarding is set up
for (LmtpCallback callback : callbacks) {
ZimbraLog.lmtp.debug("Executing callback %s", callback.getClass().getName());
callback.forwardWithoutDelivery(rd.account, rd.mbox, envSender, rcptEmail, rd.pm);
}
}
reply = LmtpReply.DELIVERY_OK;
break;
case deliver:
Account account = rd.account;
Mailbox mbox = rd.mbox;
ParsedMessage pm = rd.pm;
List<ItemId> addedMessageIds = null;
ReentrantLock lock = mailboxDeliveryLocks.get(mbox.getId());
boolean acquiredLock;
try {
// Wait for the lock, up to the timeout
acquiredLock = lock.tryLock(LC.zimbra_mailbox_lock_timeout.intValue(), TimeUnit.SECONDS);
} catch (InterruptedException e) {
acquiredLock = false;
}
if (!acquiredLock) {
ZimbraLog.lmtp.info("try again for message from=%s,to=%s: another mail delivery in progress.", envSender, rcptEmail);
reply = LmtpReply.TEMPORARY_FAILURE;
break;
}
try {
if (dedupe(pm, mbox)) {
// message was already delivered to this mailbox
ZimbraLog.lmtp.info("Not delivering message with duplicate Message-ID %s", pm.getMessageID());
} else if (mbox.dedupeForSelfMsg(pm)) {
ZimbraLog.mailbox.info("not delivering message, because it is a duplicate of sent message %s", pm.getMessageID());
} else if (recipient.getSkipFilters()) {
msgId = pm.getMessageID();
int folderId = Mailbox.ID_FOLDER_INBOX;
if (recipient.getFolder() != null) {
try {
Folder folder = mbox.getFolderByPath(null, recipient.getFolder());
folderId = folder.getId();
} catch (ServiceException se) {
if (se.getCode().equals(MailServiceException.NO_SUCH_FOLDER)) {
Folder folder = mbox.createFolder(null, recipient.getFolder(), new Folder.FolderOptions().setDefaultView(MailItem.Type.MESSAGE));
folderId = folder.getId();
} else {
throw se;
}
}
}
int flags = Flag.BITMASK_UNREAD;
if (recipient.getFlags() != null) {
flags = Flag.toBitmask(recipient.getFlags());
}
DeliveryOptions dopt = new DeliveryOptions().setFolderId(folderId);
dopt.setFlags(flags).setTags(recipient.getTags()).setRecipientEmail(rcptEmail);
Message msg = mbox.addMessage(null, pm, dopt, sharedDeliveryCtxt);
addedMessageIds = Lists.newArrayList(new ItemId(msg));
} else if (!DebugConfig.disableIncomingFilter) {
// Get msgid first, to avoid having to reopen and reparse the blob
// file if Mailbox.addMessageInternal() closes it.
pm.getMessageID();
addedMessageIds = RuleManager.applyRulesToIncomingMessage(null, mbox, pm, (int) blob.getRawSize(), rcptEmail, env, sharedDeliveryCtxt, Mailbox.ID_FOLDER_INBOX, false, true);
} else {
pm.getMessageID();
DeliveryOptions dopt = new DeliveryOptions().setFolderId(Mailbox.ID_FOLDER_INBOX);
dopt.setFlags(Flag.BITMASK_UNREAD).setRecipientEmail(rcptEmail);
Message msg = mbox.addMessage(null, pm, dopt, sharedDeliveryCtxt);
addedMessageIds = Lists.newArrayList(new ItemId(msg));
}
success = true;
if (addedMessageIds != null && addedMessageIds.size() > 0) {
addToDedupeCache(pm, mbox);
}
} finally {
lock.unlock();
}
if (addedMessageIds != null && addedMessageIds.size() > 0) {
// Execute callbacks
for (LmtpCallback callback : callbacks) {
for (ItemId id : addedMessageIds) {
if (id.belongsTo(mbox)) {
// Message was added to the local mailbox, as opposed to a mountpoint.
ZimbraLog.lmtp.debug("Executing callback %s", callback.getClass().getName());
try {
Message msg = mbox.getMessageById(null, id.getId());
callback.afterDelivery(account, mbox, envSender, rcptEmail, msg);
} catch (Throwable t) {
if (t instanceof OutOfMemoryError) {
Zimbra.halt("LMTP callback failed", t);
} else {
ZimbraLog.lmtp.warn("LMTP callback threw an exception", t);
}
}
}
}
}
}
reply = LmtpReply.DELIVERY_OK;
break;
case defer:
// Delivery to mailbox skipped. Let MTA retry again later.
// This case happens for shared delivery to a mailbox in
// backup mode.
ZimbraLog.lmtp.info("try again for message from=%s,to=%s: mailbox skipped", envSender, rcptEmail);
reply = LmtpReply.TEMPORARY_FAILURE;
break;
}
} else {
// Account or mailbox not found.
ZimbraLog.lmtp.info("rejecting message from=%s,to=%s: account or mailbox not found", envSender, rcptEmail);
reply = LmtpReply.PERMANENT_FAILURE;
}
} catch (DeliveryServiceException e) {
ZimbraLog.lmtp.info("rejecting message from=%s,to=%s: sieve filter rule", envSender, rcptEmail);
reply = LmtpReply.PERMANENT_MESSAGE_REFUSED;
} catch (ServiceException e) {
if (e.getCode().equals(MailServiceException.QUOTA_EXCEEDED)) {
ZimbraLog.lmtp.info("rejecting message from=%s,to=%s: overquota", envSender, rcptEmail);
if (config.isPermanentFailureWhenOverQuota()) {
reply = LmtpReply.PERMANENT_FAILURE_OVER_QUOTA;
} else {
reply = LmtpReply.TEMPORARY_FAILURE_OVER_QUOTA;
}
} else if (e.isReceiversFault()) {
ZimbraLog.lmtp.info("try again for message from=%s,to=%s", envSender, rcptEmail, e);
reply = LmtpReply.TEMPORARY_FAILURE;
} else {
ZimbraLog.lmtp.info("rejecting message from=%s,to=%s", envSender, rcptEmail, e);
reply = LmtpReply.PERMANENT_FAILURE;
}
} catch (Exception e) {
reply = LmtpReply.TEMPORARY_FAILURE;
ZimbraLog.lmtp.warn("try again for message from=%s,to=%s", envSender, rcptEmail, e);
} finally {
if (rd.action == DeliveryAction.deliver && !success) {
// Message was not delivered. Remove it from the dedupe
// cache so we don't dedupe it on LMTP retry.
removeFromDedupeCache(msgId, rd.mbox);
}
recipient.setDeliveryStatus(reply);
if (shared && rd != null && rd.esd) {
rd.mbox.endSharedDelivery();
rd.esd = false;
}
}
}
// If this message is being streamed from disk, cache it
ParsedMessage mimeSource = pmAttachIndex != null ? pmAttachIndex : pmNoAttachIndex;
MailboxBlob mblob = sharedDeliveryCtxt.getMailboxBlob();
if (mblob != null && mimeSource != null) {
if (bis == null) {
bis = mimeSource.getBlobInputStream();
}
if (bis != null) {
try {
// Update the MimeMessage with the blob that's stored inside the mailbox,
// since the incoming blob will be deleted.
Blob storedBlob = mblob.getLocalBlob();
bis.fileMoved(storedBlob.getFile());
MessageCache.cacheMessage(mblob.getDigest(), mimeSource.getOriginalMessage(), mimeSource.getMimeMessage());
} catch (IOException e) {
ZimbraLog.lmtp.warn("Unable to cache message for " + mblob, e);
}
}
}
} finally {
// called, we check and fix those here.
if (shared) {
for (RecipientDetail rd : rcptMap.values()) {
if (rd.esd && rd.mbox != null)
rd.mbox.endSharedDelivery();
}
}
}
}
use of com.zimbra.cs.mailbox.DeliveryOptions in project zm-mailbox by Zimbra.
the class AppendMessage method store.
private int store(Mailbox mbox, Folder folder) throws ImapSessionClosedException, ServiceException, IOException {
boolean idxAttach = mbox.attachmentsIndexingEnabled();
Long receivedDate = date != null ? date.getTime() : null;
ParsedMessage pm = new ParsedMessage(content, receivedDate, idxAttach);
try {
if (!pm.getSender().isEmpty()) {
InternetAddress ia = new JavaMailInternetAddress(pm.getSender());
if (AccountUtil.addressMatchesAccountOrSendAs(mbox.getAccount(), ia.getAddress())) {
flags |= Flag.BITMASK_FROM_ME;
}
}
} catch (Exception e) {
}
DeliveryOptions dopt = new DeliveryOptions().setFolderId(folder).setNoICal(true).setFlags(flags).setTags(tags);
Message msg = mbox.addMessage(handler.getContext(), pm, dopt, null);
if (msg != null && sflags != 0 && handler.getState() == ImapHandler.State.SELECTED) {
ImapFolder selectedFolder = handler.getSelectedFolder();
// (note that this leaves session flags unset on remote appended messages)
if (selectedFolder != null) {
ImapMessage i4msg = selectedFolder.getById(msg.getId());
if (i4msg != null) {
i4msg.setSessionFlags(sflags, selectedFolder);
}
}
}
return msg == null ? -1 : msg.getId();
}
use of com.zimbra.cs.mailbox.DeliveryOptions in project zm-mailbox by Zimbra.
the class RemoveAttachments method removeAttachmentOperation.
public static Message removeAttachmentOperation(Mailbox mbox, OperationContext octxt, ParsedMessage pm, Message msg) throws IOException, ServiceException {
if (msg.isDraft()) {
msg = mbox.saveDraft(octxt, pm, msg.getId());
} else {
int itemId = msg.getId();
DeliveryOptions dopt = new DeliveryOptions();
dopt.setFolderId(msg.getFolderId()).setNoICal(true);
dopt.setFlags(msg.getFlagBitmask()).setTags(msg.getTags());
if (msg.getConversationId() > 0)
dopt.setConversationId(msg.getConversationId());
msg = mbox.addMessage(octxt, pm, dopt, null);
// Activesync fails to add new mail_item as it has all the details of old mail_item, so it considers it as a change in mail_item Bug:102084
// Hence, set previous folder field to the mail_item with dummy folder, because of which activesync code thinks it is moved item and adds it on device.
String prevFolders = msg.getModifiedSequence() + ":" + Mailbox.ID_FOLDER_USER_ROOT;
mbox.setPreviousFolder(octxt, msg.getId(), prevFolders);
msg.getUnderlyingData().setPrevFolders(prevFolders);
// and clean up the existing message...
mbox.delete(octxt, itemId, MailItem.Type.MESSAGE);
}
return msg;
}
use of com.zimbra.cs.mailbox.DeliveryOptions in project zm-mailbox by Zimbra.
the class ArchiveFormatter method addItem.
private void addItem(UserServletContext context, Folder fldr, Map<Object, Folder> fmap, FolderDigestInfo digestInfo, Map<Integer, Integer> idMap, int[] ids, Set<MailItem.Type> types, Resolve r, ItemData id, ArchiveInputStream ais, ArchiveInputEntry aie, List<ServiceException> errs) throws ServiceException {
try {
Mailbox mbox = fldr.getMailbox();
MailItem mi = MailItem.constructItem(mbox, id.ud);
MailItem newItem = null, oldItem = null;
OperationContext octxt = context.opContext;
String path;
ParsedMessage pm;
boolean root = fldr.getId() == Mailbox.ID_FOLDER_ROOT || fldr.getId() == Mailbox.ID_FOLDER_USER_ROOT || id.path.startsWith(fldr.getPath() + '/');
if ((ids != null && Arrays.binarySearch(ids, id.ud.id) < 0) || (types != null && !types.contains(MailItem.Type.of(id.ud.type))))
return;
if (id.ud.getBlobDigest() != null && aie == null) {
addError(errs, FormatterServiceException.MISSING_BLOB(id.path));
return;
}
if (root) {
path = id.path;
} else {
path = fldr.getPath() + id.path;
}
if (path.endsWith("/") && !path.equals("/")) {
path = path.substring(0, path.length() - 1);
}
if (mbox.isImmutableSystemFolder(id.ud.folderId))
return;
switch(mi.getType()) {
case APPOINTMENT:
case TASK:
CalendarItem ci = (CalendarItem) mi;
fldr = createPath(context, fmap, path, ci.getType() == MailItem.Type.APPOINTMENT ? MailItem.Type.APPOINTMENT : MailItem.Type.TASK);
if (!root || r != Resolve.Reset) {
CalendarItem oldCI = null;
try {
oldCI = mbox.getCalendarItemByUid(octxt, ci.getUid());
} catch (Exception e) {
}
if (oldCI != null && r == Resolve.Replace) {
mbox.delete(octxt, oldCI.getId(), oldCI.getType());
} else {
oldItem = oldCI;
}
}
if (oldItem == null || r != Resolve.Skip) {
CalendarItem.AlarmData ad = ci.getAlarmData();
byte[] data = readArchiveEntry(ais, aie);
Map<Integer, MimeMessage> blobMimeMsgMap = data == null ? null : CalendarItem.decomposeBlob(data);
SetCalendarItemData defScid = new SetCalendarItemData();
SetCalendarItemData[] exceptionScids = null;
Invite[] invs = ci.getInvites();
MimeMessage mm;
if (invs != null && invs.length > 0) {
defScid.invite = invs[0];
if (blobMimeMsgMap != null && (mm = blobMimeMsgMap.get(defScid.invite.getMailItemId())) != null) {
defScid.message = new ParsedMessage(mm, mbox.attachmentsIndexingEnabled());
}
if (invs.length > 1) {
exceptionScids = new SetCalendarItemData[invs.length - 1];
for (int i = 1; i < invs.length; i++) {
SetCalendarItemData scid = new SetCalendarItemData();
scid.invite = invs[i];
if (blobMimeMsgMap != null && (mm = blobMimeMsgMap.get(defScid.invite.getMailItemId())) != null) {
scid.message = new ParsedMessage(mm, mbox.attachmentsIndexingEnabled());
}
exceptionScids[i - 1] = scid;
}
}
newItem = mbox.setCalendarItem(octxt, oldItem != null && r == Resolve.Modify ? oldItem.getFolderId() : fldr.getId(), ci.getFlagBitmask(), ci.getTags(), defScid, exceptionScids, ci.getAllReplies(), ad == null ? CalendarItem.NEXT_ALARM_KEEP_CURRENT : ad.getNextAt());
}
}
break;
case CHAT:
Chat chat = (Chat) mi;
byte[] content = readArchiveEntry(ais, aie);
pm = new ParsedMessage(content, mi.getDate(), mbox.attachmentsIndexingEnabled());
fldr = createPath(context, fmap, path, MailItem.Type.CHAT);
if (root && r != Resolve.Reset) {
Chat oldChat = null;
try {
oldChat = mbox.getChatById(octxt, chat.getId());
if (oldChat.getFolderId() != fldr.getId()) {
oldChat = null;
}
} catch (Exception e) {
}
if (oldChat != null && chat.getSender().equals(oldChat.getSender()) && chat.getSubject().equals(oldChat.getSubject())) {
if (r == Resolve.Replace) {
mbox.delete(octxt, oldChat.getId(), oldChat.getType());
} else {
oldItem = oldChat;
if (r == Resolve.Modify)
newItem = mbox.updateChat(octxt, pm, oldItem.getId());
}
}
}
if (oldItem == null)
newItem = mbox.createChat(octxt, pm, fldr.getId(), chat.getFlagBitmask(), chat.getTags());
break;
case CONVERSATION:
Conversation cv = (Conversation) mi;
if (r != Resolve.Reset && r != Resolve.Skip) {
try {
oldItem = mbox.getConversationByHash(octxt, Mailbox.getHash(cv.getSubject()));
} catch (Exception e) {
}
}
break;
case CONTACT:
Contact ct = (Contact) mi;
fldr = createPath(context, fmap, path, Folder.Type.CONTACT);
if (root && r != Resolve.Reset) {
Contact oldContact = null;
oldContact = findContact(octxt, mbox, ct, fldr);
if (oldContact != null) {
String email = string(ct.get(ContactConstants.A_email));
String first = string(ct.get(ContactConstants.A_firstName));
String name = string(ct.get(ContactConstants.A_fullName));
String oldemail = string(oldContact.get(ContactConstants.A_email));
String oldfirst = string(oldContact.get(ContactConstants.A_firstName));
String oldname = string(oldContact.get(ContactConstants.A_fullName));
if (email.equals(oldemail) && first.equals(oldfirst) && name.equals(oldname)) {
if (r == Resolve.Replace) {
mbox.delete(octxt, oldContact.getId(), oldContact.getType());
} else {
oldItem = oldContact;
if (r == Resolve.Modify) {
mbox.modifyContact(octxt, oldItem.getId(), new ParsedContact(ct.getFields(), readArchiveEntry(ais, aie)));
}
}
}
}
}
if (oldItem == null) {
newItem = mbox.createContact(octxt, new ParsedContact(ct.getFields(), readArchiveEntry(ais, aie)), fldr.getId(), ct.getTags());
}
break;
case DOCUMENT:
case WIKI:
Document doc = (Document) mi;
Document oldDoc = null;
Integer oldId = idMap.get(mi.getId());
fldr = createParent(context, fmap, path, doc.getType() == MailItem.Type.DOCUMENT ? MailItem.Type.DOCUMENT : MailItem.Type.WIKI);
if (oldId == null) {
try {
for (Document listDoc : mbox.getDocumentList(octxt, fldr.getId())) {
if (doc.getName().equals(listDoc.getName())) {
oldDoc = listDoc;
idMap.put(doc.getId(), oldDoc.getId());
break;
}
}
} catch (Exception e) {
}
} else {
oldDoc = mbox.getDocumentById(octxt, oldId);
}
if (oldDoc != null) {
if (r == Resolve.Replace && oldId == null) {
mbox.delete(octxt, oldDoc.getId(), oldDoc.getType());
} else if (doc.getVersion() < oldDoc.getVersion()) {
return;
} else {
oldItem = oldDoc;
if (doc.getVersion() > oldDoc.getVersion()) {
newItem = mbox.addDocumentRevision(octxt, oldDoc.getId(), doc.getCreator(), doc.getName(), doc.getDescription(), doc.isDescriptionEnabled(), ais.getInputStream());
}
if (r != Resolve.Skip) {
mbox.setDate(octxt, oldDoc.getId(), doc.getType(), doc.getDate());
}
}
}
if (oldItem == null) {
if (mi.getType() == MailItem.Type.DOCUMENT) {
newItem = mbox.createDocument(octxt, fldr.getId(), doc.getName(), doc.getContentType(), doc.getCreator(), doc.getDescription(), ais.getInputStream());
} else {
WikiItem wi = (WikiItem) mi;
newItem = mbox.createWiki(octxt, fldr.getId(), wi.getWikiWord(), wi.getCreator(), wi.getDescription(), ais.getInputStream());
}
mbox.setDate(octxt, newItem.getId(), doc.getType(), doc.getDate());
idMap.put(doc.getId(), newItem.getId());
}
break;
case FLAG:
return;
case FOLDER:
String aclParam = context.params.get("acl");
boolean doACL = aclParam == null || !aclParam.equals("0");
Folder f = (Folder) mi;
ACL acl = f.getACL();
Folder oldF = null;
MailItem.Type view = f.getDefaultView();
if (view == MailItem.Type.CONVERSATION || view == MailItem.Type.FLAG || view == MailItem.Type.TAG)
break;
try {
oldF = mbox.getFolderByPath(octxt, path);
} catch (Exception e) {
}
if (oldF != null) {
oldItem = oldF;
if (r != Resolve.Skip) {
if (!f.getUrl().equals(oldF.getUrl())) {
mbox.setFolderUrl(octxt, oldF.getId(), f.getUrl());
}
if (doACL) {
ACL oldACL = oldF.getACL();
if ((acl == null && oldACL != null) || (acl != null && (oldACL == null || !acl.equals(oldACL)))) {
mbox.setPermissions(octxt, oldF.getId(), acl);
}
}
}
}
if (oldItem == null) {
fldr = createParent(context, fmap, path, Folder.Type.UNKNOWN);
Folder.FolderOptions fopt = new Folder.FolderOptions();
fopt.setDefaultView(f.getDefaultView()).setFlags(f.getFlagBitmask()).setColor(f.getColor()).setUrl(f.getUrl());
newItem = fldr = mbox.createFolder(octxt, f.getName(), fldr.getId(), fopt);
if (doACL && acl != null) {
mbox.setPermissions(octxt, fldr.getId(), acl);
}
fmap.put(fldr.getId(), fldr);
fmap.put(fldr.getPath(), fldr);
}
break;
case MESSAGE:
Message msg = (Message) mi;
Message oldMsg = null;
fldr = createPath(context, fmap, path, Folder.Type.MESSAGE);
if (root && r != Resolve.Reset) {
try {
oldMsg = mbox.getMessageById(octxt, msg.getId());
if (!msg.getDigest().equals(oldMsg.getDigest()) || oldMsg.getFolderId() != fldr.getId()) {
oldMsg = null;
}
} catch (Exception e) {
}
}
if (oldMsg == null) {
Integer digestId = digestInfo.getIdForDigest(fldr, mi.getDigest());
if (digestId != null) {
oldMsg = mbox.getMessageById(octxt, digestId);
if (!msg.getDigest().equals(oldMsg.getDigest())) {
oldMsg = null;
}
}
}
if (oldMsg != null) {
if (r == Resolve.Replace) {
ZimbraLog.misc.debug("Deleting old msg with id=%s as has same digest='%s'", oldMsg.getId(), mi.getDigest());
mbox.delete(octxt, oldMsg.getId(), oldMsg.getType());
} else {
oldItem = oldMsg;
}
}
if (oldItem != null) {
ZimbraLog.misc.debug("Message with id=%s has same digest='%s' - not re-adding", oldItem.getId(), mi.getDigest());
} else {
DeliveryOptions opt = new DeliveryOptions().setFolderId(fldr.getId()).setNoICal(true).setFlags(msg.getFlagBitmask()).setTags(msg.getTags());
newItem = mbox.addMessage(octxt, ais.getInputStream(), (int) aie.getSize(), msg.getDate(), opt, null, id);
}
break;
case MOUNTPOINT:
Mountpoint mp = (Mountpoint) mi;
MailItem oldMP = null;
try {
oldMP = mbox.getItemByPath(octxt, path);
if (oldMP.getType() == mi.getType()) {
oldMP = null;
}
} catch (Exception e) {
}
if (oldMP != null) {
if (r == Resolve.Modify || r == Resolve.Replace) {
mbox.delete(octxt, oldMP.getId(), oldMP.getType());
} else {
oldItem = oldMP;
}
}
if (oldItem == null) {
fldr = createParent(context, fmap, path, Folder.Type.UNKNOWN);
newItem = mbox.createMountpoint(context.opContext, fldr.getId(), mp.getName(), mp.getOwnerId(), mp.getRemoteId(), mp.getRemoteUuid(), mp.getDefaultView(), mp.getFlagBitmask(), mp.getColor(), mp.isReminderEnabled());
}
break;
case NOTE:
Note note = (Note) mi;
Note oldNote = null;
fldr = createPath(context, fmap, path, MailItem.Type.NOTE);
try {
for (Note listNote : mbox.getNoteList(octxt, fldr.getId())) {
if (note.getSubject().equals(listNote.getSubject())) {
oldNote = listNote;
break;
}
}
} catch (Exception e) {
}
if (oldNote != null) {
if (r == Resolve.Replace) {
mbox.delete(octxt, oldNote.getId(), oldNote.getType());
} else {
oldItem = oldNote;
if (r == Resolve.Modify) {
mbox.editNote(octxt, oldItem.getId(), new String(readArchiveEntry(ais, aie), UTF8));
}
}
break;
}
if (oldItem == null) {
newItem = mbox.createNote(octxt, new String(readArchiveEntry(ais, aie), UTF8), note.getBounds(), note.getColor(), fldr.getId());
}
break;
case SEARCHFOLDER:
SearchFolder sf = (SearchFolder) mi;
MailItem oldSF = null;
try {
oldSF = mbox.getItemByPath(octxt, path);
if (oldSF.getType() == mi.getType()) {
oldSF = null;
}
} catch (Exception e) {
}
if (oldSF != null) {
if (r == Resolve.Modify) {
mbox.modifySearchFolder(octxt, oldSF.getId(), sf.getQuery(), sf.getReturnTypes(), sf.getSortField());
} else if (r == Resolve.Replace) {
mbox.delete(octxt, oldSF.getId(), oldSF.getType());
} else {
oldItem = oldSF;
}
}
if (oldItem == null) {
fldr = createParent(context, fmap, path, MailItem.Type.UNKNOWN);
newItem = mbox.createSearchFolder(octxt, fldr.getId(), sf.getName(), sf.getQuery(), sf.getReturnTypes(), sf.getSortField(), sf.getFlagBitmask(), sf.getColor());
}
break;
case TAG:
Tag tag = (Tag) mi;
try {
Tag oldTag = mbox.getTagByName(octxt, tag.getName());
oldItem = oldTag;
} catch (Exception e) {
}
if (oldItem == null) {
newItem = mbox.createTag(octxt, tag.getName(), tag.getColor());
}
break;
case VIRTUAL_CONVERSATION:
return;
}
if (newItem != null) {
if (mi.getColor() != newItem.getColor()) {
mbox.setColor(octxt, newItem.getId(), newItem.getType(), mi.getColor());
}
if (!id.flags.equals(newItem.getFlagString()) || !id.tagsEqual(newItem)) {
mbox.setTags(octxt, newItem.getId(), newItem.getType(), Flag.toBitmask(id.flags), getTagNames(id), null);
}
} else if (oldItem != null && r == Resolve.Modify) {
if (mi.getColor() != oldItem.getColor()) {
mbox.setColor(octxt, oldItem.getId(), oldItem.getType(), mi.getColor());
}
if (!id.flags.equals(oldItem.getFlagString()) || !id.tagsEqual(oldItem)) {
mbox.setTags(octxt, oldItem.getId(), oldItem.getType(), Flag.toBitmask(id.flags), getTagNames(id), null);
}
}
} catch (MailServiceException e) {
if (e.getCode() == MailServiceException.QUOTA_EXCEEDED) {
throw e;
} else if (r != Resolve.Skip || e.getCode() != MailServiceException.ALREADY_EXISTS) {
addError(errs, e);
}
} catch (Exception e) {
String path = id.path;
// When importing items into, e.g. the Inbox, often path is just "/Inbox" which isn't that useful
if ((aie != null) && !Strings.isNullOrEmpty(aie.getName())) {
path = aie.getName();
}
addError(errs, FormatterServiceException.UNKNOWN_ERROR(path, e));
}
}
use of com.zimbra.cs.mailbox.DeliveryOptions in project zm-mailbox by Zimbra.
the class NativeFormatter method saveCallback.
@Override
public void saveCallback(UserServletContext context, String contentType, Folder folder, String filename) throws IOException, ServiceException, UserServletException {
if (filename == null) {
Mailbox mbox = folder.getMailbox();
try {
ParsedMessage pm = new ParsedMessage(context.getPostBody(), mbox.attachmentsIndexingEnabled());
DeliveryOptions dopt = new DeliveryOptions().setFolderId(folder).setNoICal(true);
mbox.addMessage(context.opContext, pm, dopt, null);
return;
} catch (ServiceException e) {
throw new UserServletException(HttpServletResponse.SC_BAD_REQUEST, "error parsing message");
}
}
InputStream is = context.getRequestInputStream();
try {
Blob blob = StoreManager.getInstance().storeIncoming(is);
saveDocument(blob, context, contentType, folder, filename, is);
} finally {
is.close();
}
}
Aggregations