use of com.zimbra.cs.mailbox.MailItem 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.MailItem in project zm-mailbox by Zimbra.
the class AtomFormatter method formatCallback.
@Override
public void formatCallback(UserServletContext context) throws IOException, ServiceException {
Iterator<? extends MailItem> iterator = null;
StringBuffer sb = new StringBuffer();
Element.XMLElement feed = new Element.XMLElement("feed");
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/atom+xml");
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
feed.addAttribute("xmlns", "http://www.w3.org/2005/Atom");
feed.addElement("title").setText("Zimbra " + context.itemPath);
feed.addElement("generator").setText("Zimbra Atom Feed Servlet");
feed.addElement("id").setText(context.req.getRequestURL().toString());
feed.addElement("updated").setText(DateUtil.toISO8601(new Date(context.targetMailbox.getLastChangeDate())));
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, feed, context);
}
} else if (itItem instanceof Message) {
addMessage((Message) itItem, feed);
}
}
}
} finally {
if (iterator instanceof QueryResultIterator)
((QueryResultIterator) iterator).finished();
}
sb.append(feed.toString());
context.resp.getOutputStream().write(sb.toString().getBytes("UTF-8"));
}
use of com.zimbra.cs.mailbox.MailItem in project zm-mailbox by Zimbra.
the class NativeFormatter method saveDocument.
private void saveDocument(Blob blob, UserServletContext context, String contentType, Folder folder, String filename, InputStream is) throws IOException, ServiceException, UserServletException {
Mailbox mbox = folder.getMailbox();
MailItem item = null;
String creator = context.getAuthAccount() == null ? null : context.getAuthAccount().getName();
ParsedDocument pd = null;
try {
if (contentType == null) {
contentType = MimeDetect.getMimeDetect().detect(filename);
if (contentType == null)
contentType = MimeConstants.CT_APPLICATION_OCTET_STREAM;
}
pd = new ParsedDocument(blob, filename, contentType, System.currentTimeMillis(), creator, context.req.getHeader("X-Zimbra-Description"), true);
item = mbox.getItemByPath(context.opContext, filename, folder.getId());
// XXX: should we just overwrite here instead?
if (!(item instanceof Document))
throw new UserServletException(HttpServletResponse.SC_BAD_REQUEST, "cannot overwrite existing object at that path");
// scan upload for viruses
StringBuffer info = new StringBuffer();
UploadScanner.Result result = UploadScanner.acceptStream(is, info);
if (result == UploadScanner.REJECT)
throw MailServiceException.UPLOAD_REJECTED(filename, info.toString());
if (result == UploadScanner.ERROR)
throw MailServiceException.SCAN_ERROR(filename);
item = mbox.addDocumentRevision(context.opContext, item.getId(), pd);
} catch (NoSuchItemException nsie) {
item = mbox.createDocument(context.opContext, folder.getId(), pd, MailItem.Type.DOCUMENT, 0);
}
sendZimbraHeaders(context, context.resp, item);
}
use of com.zimbra.cs.mailbox.MailItem in project zm-mailbox by Zimbra.
the class SaveDocument method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
OperationContext octxt = getOperationContext(zsc, context);
Element docElem = request.getElement(MailConstants.E_DOC);
Doc doc = null;
Element response = null;
boolean success = false;
Mailbox mbox = null;
int folderId = 0;
try {
String explicitName = docElem.getAttribute(MailConstants.A_NAME, null);
String explicitCtype = docElem.getAttribute(MailConstants.A_CONTENT_TYPE, null);
//bug 37180, extract the filename from the path (for IE). IE sends the full path.
if (explicitName != null) {
try {
explicitName = explicitName.replaceAll("\\\\", "/");
explicitName = explicitName.substring(explicitName.lastIndexOf("/") + 1);
} catch (Exception e) {
//Do nothing
}
}
String description = docElem.getAttribute(MailConstants.A_DESC, null);
ItemId fid = new ItemId(docElem.getAttribute(MailConstants.A_FOLDER, DEFAULT_DOCUMENT_FOLDER), zsc);
folderId = fid.getId();
String id = docElem.getAttribute(MailConstants.A_ID, null);
int itemId = id == null ? 0 : new ItemId(id, zsc).getId();
int ver = (int) docElem.getAttributeLong(MailConstants.A_VERSION, 0);
mbox = getRequestedMailbox(zsc);
Element attElem = docElem.getOptionalElement(MailConstants.E_UPLOAD);
Element msgElem = docElem.getOptionalElement(MailConstants.E_MSG);
Element docRevElem = docElem.getOptionalElement(MailConstants.E_DOC);
if (attElem != null) {
String aid = attElem.getAttribute(MailConstants.A_ID, null);
doc = getUploadedDoc(aid, zsc, explicitName, explicitCtype, description);
} else if (msgElem != null) {
String part = msgElem.getAttribute(MailConstants.A_PART);
ItemId iid = new ItemId(msgElem.getAttribute(MailConstants.A_ID), zsc);
doc = fetchMimePart(octxt, zsc.getAuthToken(), iid, part, explicitName, explicitCtype, description);
} else if (docRevElem != null) {
ItemId iid = new ItemId(docRevElem.getAttribute(MailConstants.A_ID), zsc);
int revSource = (int) docRevElem.getAttributeLong(MailConstants.A_VERSION, 0);
Account sourceAccount = Provisioning.getInstance().getAccountById(iid.getAccountId());
if (sourceAccount.getId().equals(zsc.getRequestedAccountId())) {
Document docRev;
if (revSource == 0) {
docRev = mbox.getDocumentById(octxt, iid.getId());
} else {
docRev = (Document) mbox.getItemRevision(octxt, iid.getId(), MailItem.Type.DOCUMENT, revSource);
}
doc = new Doc(docRev);
} else {
doc = new Doc(zsc.getAuthToken(), sourceAccount, iid.getId(), revSource);
}
// the content from another document
if (ver != 0) {
doc.name = null;
}
} else {
String inlineContent = docElem.getAttribute(MailConstants.E_CONTENT);
doc = new Doc(inlineContent, explicitName, explicitCtype, description);
}
// set content-type based on file extension.
setDocContentType(doc);
Document docItem = null;
InputStream is = null;
try {
is = doc.getInputStream();
} catch (IOException e) {
throw ServiceException.FAILURE("can't save document", e);
}
if (itemId == 0) {
// create a new page
docItem = createDocument(doc, zsc, octxt, mbox, docElem, is, folderId, MailItem.Type.DOCUMENT);
} else {
// add a new revision
docItem = mbox.getDocumentById(octxt, itemId);
if (docItem.getVersion() != ver) {
throw MailServiceException.MODIFY_CONFLICT(new Argument(MailConstants.A_NAME, doc.name, Argument.Type.STR), new Argument(MailConstants.A_ID, itemId, Argument.Type.IID), new Argument(MailConstants.A_VERSION, docItem.getVersion(), Argument.Type.NUM));
}
String name = docItem.getName();
if (doc.name != null) {
name = doc.name;
}
boolean descEnabled = docElem.getAttributeBool(MailConstants.A_DESC_ENABLED, docItem.isDescriptionEnabled());
docItem = mbox.addDocumentRevision(octxt, itemId, getAuthor(zsc), name, doc.description, descEnabled, is);
}
response = zsc.createElement(MailConstants.SAVE_DOCUMENT_RESPONSE);
Element m = response.addElement(MailConstants.E_DOC);
m.addAttribute(MailConstants.A_ID, new ItemIdFormatter(zsc).formatItemId(docItem));
m.addAttribute(MailConstants.A_VERSION, docItem.getVersion());
m.addAttribute(MailConstants.A_NAME, docItem.getName());
success = true;
} catch (ServiceException e) {
if (e.getCode().equals(MailServiceException.ALREADY_EXISTS)) {
MailItem item = null;
if (mbox != null && folderId != 0) {
item = mbox.getItemByPath(octxt, doc.name, folderId);
}
if (item != null && item instanceof Document) {
// name clash with another Document
throw MailServiceException.ALREADY_EXISTS("name " + doc.name + " in folder " + folderId, doc.name, item.getId(), ((Document) item).getVersion());
} else if (item != null) {
// name clash with a folder
throw MailServiceException.ALREADY_EXISTS("name " + doc.name + " in folder " + folderId, doc.name, item.getId());
}
}
throw e;
} finally {
if (success && doc != null) {
doc.cleanup();
}
}
return response;
}
use of com.zimbra.cs.mailbox.MailItem in project zm-mailbox by Zimbra.
the class ArchiveFormatter method saveItem.
private ArchiveOutputStream saveItem(UserServletContext context, MailItem mi, Map<Integer, String> fldrs, Map<Integer, Integer> cnts, boolean version, ArchiveOutputStream aos, CharsetEncoder charsetEncoder, Set<String> names) throws ServiceException {
String ext = null, name = null;
String extra = null;
Integer fid = mi.getFolderId();
String fldr;
InputStream is = null;
String metaParam = context.params.get(UserServlet.QP_META);
boolean meta = metaParam == null ? getDefaultMeta() : !metaParam.equals("0");
if (!version && mi.isTagged(Flag.FlagInfo.VERSIONED)) {
for (MailItem rev : context.targetMailbox.getAllRevisions(context.opContext, mi.getId(), mi.getType())) {
if (mi.getVersion() != rev.getVersion())
aos = saveItem(context, rev, fldrs, cnts, true, aos, charsetEncoder, names);
}
}
switch(mi.getType()) {
case APPOINTMENT:
Appointment appt = (Appointment) mi;
if (!appt.isPublic() && !appt.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges())) {
return aos;
}
if (meta) {
name = appt.getSubject();
ext = "appt";
} else {
ext = "ics";
}
break;
case CHAT:
ext = "chat";
break;
case CONTACT:
Contact ct = (Contact) mi;
name = ct.getFileAsString();
if (!meta) {
ext = "vcf";
}
break;
case FLAG:
return aos;
case FOLDER:
case MOUNTPOINT:
case SEARCHFOLDER:
if (mi.getId() == Mailbox.ID_FOLDER_ROOT) {
name = "ROOT";
} else if (mi.getId() == Mailbox.ID_FOLDER_USER_ROOT) {
name = "USER_ROOT";
} else {
name = mi.getName();
}
break;
case MESSAGE:
Message msg = (Message) mi;
if (msg.hasCalendarItemInfos()) {
Set<ItemId> calItems = Sets.newHashSet();
for (Iterator<CalendarItemInfo> it = msg.getCalendarItemInfoIterator(); it.hasNext(); ) {
ItemId iid = it.next().getCalendarItemId();
if (iid != null) {
calItems.add(iid);
}
}
for (ItemId i : calItems) {
if (extra == null) {
extra = "calendar=" + i.toString();
} else {
extra += ',' + i.toString();
}
}
}
ext = "eml";
break;
case NOTE:
ext = "note";
break;
case TASK:
Task task = (Task) mi;
if (!task.isPublic() && !task.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges())) {
return aos;
}
ext = "task";
break;
case VIRTUAL_CONVERSATION:
return aos;
case WIKI:
ext = "wiki";
break;
}
fldr = fldrs.get(fid);
if (fldr == null) {
Folder f = mi.getMailbox().getFolderById(context.opContext, fid);
cnts.put(fid, 1);
fldr = f.getPath();
if (fldr.startsWith("/")) {
fldr = fldr.substring(1);
}
fldr = sanitize(fldr, charsetEncoder);
fldr = ILLEGAL_FOLDER_CHARS.matcher(fldr).replaceAll("_");
fldrs.put(fid, fldr);
} else if (!(mi instanceof Folder)) {
final int BATCH = 500;
int cnt = cnts.get(fid) + 1;
cnts.put(fid, cnt);
cnt /= BATCH;
if (cnt > 0) {
fldr = fldr + '!' + cnt;
}
}
int targetBaseLength = 0;
if (context.noHierarchy()) {
// Parent hierarchy is not needed, so construct the folder names without parent hierarchy.
// e.g> represent "inbox/subfolder/target" as "target".
String targetPath = null;
if (context.itemPath.endsWith("/")) {
// inbox/subfolder/target/
targetPath = context.itemPath.substring(0, context.itemPath.lastIndexOf("/"));
} else {
// inbox/subfolder/target
targetPath = context.itemPath;
}
// "inbox/subfolder".length()
targetBaseLength = targetPath.lastIndexOf('/');
if (targetBaseLength >= fldr.length()) {
// fldr is "inbox/subfolder"
fldr = "";
} else if (targetBaseLength > 0) {
// fldr is "inbox/subfolder/target"
fldr = fldr.substring(targetBaseLength + 1);
}
}
try {
ArchiveOutputEntry aoe;
byte[] data = null;
String path = mi instanceof Contact ? getEntryName(mi, fldr, name, ext, charsetEncoder, names) : getEntryName(mi, fldr, name, ext, charsetEncoder, !(mi instanceof Document));
long miSize = mi.getSize();
if (miSize == 0 && mi.getDigest() != null) {
ZimbraLog.misc.debug("blob db size 0 for item %d", mi.getId());
return aos;
}
try {
is = mi.getContentStream();
} catch (Exception e) {
ZimbraLog.misc.error("missing blob for item %d: expected %d", mi.getId(), miSize);
return aos;
}
if (aos == null) {
aos = getOutputStream(context, charsetEncoder.charset().name());
}
if ((mi instanceof CalendarItem) && (context.getStartTime() != TIME_UNSPECIFIED || context.getEndTime() != TIME_UNSPECIFIED)) {
Collection<Instance> instances = ((CalendarItem) mi).expandInstances(context.getStartTime(), context.getEndTime(), false);
if (instances.isEmpty()) {
return aos;
}
}
aoe = aos.newOutputEntry(path + ".meta", mi.getType().toString(), mi.getType().toByte(), mi.getDate());
if (mi instanceof Message && (mi.getFlagBitmask() & Flag.ID_UNREAD) != 0) {
aoe.setUnread();
}
if (meta) {
ItemData itemData = new ItemData(mi, extra);
if (context.noHierarchy()) {
// itemData.path is of the form /Inbox/subfolder/target and after this step it becomes /target.
if (targetBaseLength > 0 && ((targetBaseLength + 1) < itemData.path.length())) {
itemData.path = itemData.path.substring(targetBaseLength + 1);
}
}
byte[] metaData = itemData.encode();
aoe.setSize(metaData.length);
aos.putNextEntry(aoe);
aos.write(metaData);
aos.closeEntry();
} else if (mi instanceof CalendarItem) {
Browser browser = HttpUtil.guessBrowser(context.req);
List<CalendarItem> calItems = new ArrayList<CalendarItem>();
boolean needAppleICalHacks = Browser.APPLE_ICAL.equals(browser);
boolean useOutlookCompatMode = Browser.IE.equals(browser);
OperationContext octxt = new OperationContext(context.getAuthAccount(), context.isUsingAdminPrivileges());
StringWriter writer = new StringWriter();
calItems.add((CalendarItem) mi);
context.targetMailbox.writeICalendarForCalendarItems(writer, octxt, calItems, useOutlookCompatMode, true, needAppleICalHacks, true);
data = writer.toString().getBytes(charsetEncoder.charset());
} else if (mi instanceof Contact) {
VCard vcf = VCard.formatContact((Contact) mi);
data = vcf.getFormatted().getBytes(charsetEncoder.charset());
} else if (mi instanceof Message) {
if (context.hasPart()) {
MimeMessage mm = ((Message) mi).getMimeMessage();
Set<String> attachmentNames = new HashSet<String>();
for (String part : context.getPart().split(",")) {
BufferStream bs;
MimePart mp = Mime.getMimePart(mm, part);
long sz;
if (mp == null) {
throw MailServiceException.NO_SUCH_PART(part);
}
name = Mime.getFilename(mp);
ext = null;
sz = mp.getSize();
if (sz == -1) {
sz = miSize;
}
if (name == null) {
name = "attachment";
} else {
int dot = name.lastIndexOf('.');
if (dot != -1 && dot < name.length() - 1) {
ext = name.substring(dot + 1);
name = name.substring(0, dot);
}
}
bs = new BufferStream(sz, 1024 * 1024);
InputStream stream = mp.getInputStream();
try {
bs.readFrom(stream);
} finally {
// close the stream, it could be an instance of PipedInputStream.
ByteUtil.closeStream(stream);
}
aoe = aos.newOutputEntry(getEntryName(mi, "", name, ext, charsetEncoder, attachmentNames), mi.getType().toString(), mi.getType().toByte(), mi.getDate());
sz = bs.getSize();
aoe.setSize(sz);
aos.putNextEntry(aoe);
bs.copyTo(aos.getOutputStream());
bs.close();
aos.closeEntry();
}
return aos;
}
}
aoe = aos.newOutputEntry(path, mi.getType().toString(), mi.getType().toByte(), mi.getDate());
if (data != null) {
aoe.setSize(data.length);
aos.putNextEntry(aoe);
aos.write(data);
aos.closeEntry();
} else if (is != null) {
if (context.shouldReturnBody()) {
byte[] buf = new byte[aos.getRecordSize() * 20];
int in;
long remain = miSize;
aoe.setSize(miSize);
aos.putNextEntry(aoe);
while (remain > 0 && (in = is.read(buf)) >= 0) {
aos.write(buf, 0, remain < in ? (int) remain : in);
remain -= in;
}
if (remain != 0) {
ZimbraLog.misc.error("mismatched blob size for item %d: expected %d", mi.getId(), miSize);
if (remain > 0) {
Arrays.fill(buf, (byte) ' ');
while (remain > 0) {
aos.write(buf, 0, remain < buf.length ? (int) remain : buf.length);
remain -= buf.length;
}
}
aos.closeEntry();
aoe = aos.newOutputEntry(path + ".err", mi.getType().toString(), mi.getType().toByte(), mi.getDate());
aoe.setSize(0);
aos.putNextEntry(aoe);
}
} else {
// Read headers into memory to compute size
byte[] headerData = HeadersOnlyInputStream.getHeaders(is);
aoe.setSize(headerData.length);
aos.putNextEntry(aoe);
aos.write(headerData);
}
aos.closeEntry();
}
} catch (Exception e) {
throw ServiceException.FAILURE("archive error", e);
} finally {
ByteUtil.closeStream(is);
}
return aos;
}
Aggregations