use of com.zimbra.cs.mailbox.MailItem in project zm-mailbox by Zimbra.
the class UrlNamespace method getMailItemResource.
/**
*
* @param ctxt
* @param user
* @param path - May contain parameters
* @return
*/
private static DavResource getMailItemResource(DavContext ctxt, String user, String path) throws ServiceException, DavException {
Provisioning prov = Provisioning.getInstance();
Account account = prov.get(AccountBy.name, user);
if (account == null) {
// Anti-account name harvesting.
ZimbraLog.dav.info("Failing GET of mail item resource - no such account '%s' path '%s'", user, path);
throw new DavException("Request denied", HttpServletResponse.SC_NOT_FOUND, null);
}
if (ctxt.getUser().compareTo(user) != 0 || !Provisioning.onLocalServer(account)) {
try {
return new RemoteCollection(ctxt, path, account);
} catch (MailServiceException.NoSuchItemException e) {
return null;
}
}
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
int id = 0;
int index = path.indexOf('?');
if (index > 0) {
Map<String, String> params = HttpUtil.getURIParams(path.substring(index + 1));
path = path.substring(0, index);
if (params.containsKey("id")) {
try {
id = Integer.parseInt(params.get("id"));
} catch (NumberFormatException e) {
}
}
}
// At this point, path will have had any parameters stripped from it
OperationContext octxt = ctxt.getOperationContext();
MailItem item = null;
// simple case. root folder or if id is specified.
if (path.equals("/")) {
item = mbox.getFolderByPath(octxt, "/");
} else if (id > 0) {
item = mbox.getItemById(octxt, id, MailItem.Type.UNKNOWN);
}
if (item != null) {
return getResourceFromMailItem(ctxt, item);
}
// check for named items (folders, documents)
try {
return getResourceFromMailItem(ctxt, mbox.getItemByPath(octxt, path));
} catch (MailServiceException.NoSuchItemException e) {
}
// check if the this is renamed folder.
DavResource rs = checkRenamedResource(user, path);
if (rs != null)
return rs;
// look up the item from path
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
index = path.lastIndexOf('/');
String folderPath = path.substring(0, index);
String baseName = path.substring(index + 1);
Folder f = null;
if (index != -1) {
try {
f = mbox.getFolderByPath(octxt, folderPath);
} catch (MailServiceException.NoSuchItemException e) {
}
}
if (f != null) {
/* First check whether the default name has been over-ridden - perhaps because the name was
* chosen by a DAV client via PUT to a URL when creating the item. */
DavNames.DavName davName = null;
if (DebugConfig.enableDAVclientCanChooseResourceBaseName) {
davName = DavNames.DavName.create(mbox.getId(), f.getId(), baseName);
}
if (davName != null) {
Integer itemId = DavNames.get(davName);
if (itemId != null) {
item = mbox.getItemById(octxt, itemId, MailItem.Type.UNKNOWN);
if ((item != null) && (f.getId() == item.getFolderId())) {
return getResourceFromMailItem(ctxt, item);
}
item = null;
}
}
if (baseName.toLowerCase().endsWith(CalendarObject.CAL_EXTENSION)) {
String uid = baseName.substring(0, baseName.length() - CalendarObject.CAL_EXTENSION.length());
// Unescape the name (It was encoded in DavContext intentionally)
uid = HttpUtil.urlUnescape(uid);
index = uid.indexOf(',');
if (index > 0) {
try {
id = Integer.parseInt(uid.substring(index + 1));
} catch (NumberFormatException e) {
}
}
if (id > 0) {
item = mbox.getItemById(octxt, id, MailItem.Type.UNKNOWN);
} else {
item = mbox.getCalendarItemByUid(octxt, uid);
}
if ((item != null) && (f.getId() != item.getFolderId())) {
item = null;
}
} else if (baseName.toLowerCase().endsWith(AddressObject.VCARD_EXTENSION)) {
rs = AddressObject.getAddressObjectByUID(ctxt, baseName, account, f);
if (rs != null) {
return rs;
}
} else if (f.getId() == Mailbox.ID_FOLDER_INBOX || f.getId() == Mailbox.ID_FOLDER_SENT) {
ctxt.setActingAsDelegateFor(baseName);
// delegated scheduling and notification handling
return getResourceFromMailItem(ctxt, f);
}
}
return getResourceFromMailItem(ctxt, item);
}
use of com.zimbra.cs.mailbox.MailItem in project zm-mailbox by Zimbra.
the class UrlNamespace method getResourceFromMailItem.
/* Returns DavResource for the MailItem. */
public static DavResource getResourceFromMailItem(DavContext ctxt, MailItem item) throws DavException {
DavResource resource = null;
if (item == null) {
return resource;
}
MailItem.Type itemType = item.getType();
try {
MailItem.Type viewType;
switch(itemType) {
case MOUNTPOINT:
Mountpoint mp = (Mountpoint) item;
viewType = mp.getDefaultView();
// don't expose mounted calendars when using iCal style delegation model.
if (!ctxt.useIcalDelegation() && viewType == MailItem.Type.APPOINTMENT) {
resource = new RemoteCalendarCollection(ctxt, mp);
} else {
resource = new RemoteCollection(ctxt, mp);
}
break;
case FOLDER:
Folder f = (Folder) item;
viewType = f.getDefaultView();
if (f.getId() == Mailbox.ID_FOLDER_INBOX && DavResource.isSchedulingEnabled()) {
resource = new ScheduleInbox(ctxt, f);
} else if (f.getId() == Mailbox.ID_FOLDER_SENT && DavResource.isSchedulingEnabled()) {
resource = new ScheduleOutbox(ctxt, f);
} else if (viewType == MailItem.Type.APPOINTMENT || viewType == MailItem.Type.TASK) {
resource = getCalendarCollection(ctxt, f);
} else if (viewType == MailItem.Type.CONTACT) {
resource = new AddressbookCollection(ctxt, f);
} else {
resource = new Collection(ctxt, f);
}
break;
case DOCUMENT:
resource = new Notebook(ctxt, (Document) item);
break;
case APPOINTMENT:
case TASK:
resource = new CalendarObject.LocalCalendarObject(ctxt, (CalendarItem) item);
break;
case MESSAGE:
resource = getCalendarItemForMessage(ctxt, (Message) item);
break;
case CONTACT:
resource = new AddressObject(ctxt, (Contact) item);
break;
}
} catch (ServiceException e) {
resource = null;
ZimbraLog.dav.info("cannot create DavResource", e);
}
return resource;
}
use of com.zimbra.cs.mailbox.MailItem in project zm-mailbox by Zimbra.
the class DbMailItem method icopy.
public static void icopy(MailItem source, UnderlyingData data, boolean shared) throws ServiceException {
Mailbox mbox = source.getMailbox();
if (data == null || data.id <= 0 || data.folderId <= 0 || data.parentId == 0) {
throw ServiceException.FAILURE("invalid data for DB item i-copy", null);
}
checkNamingConstraint(mbox, data.folderId, source.getName(), data.id);
DbConnection conn = mbox.getOperationConnection();
PreparedStatement stmt = null;
try {
String table = getMailItemTableName(mbox);
String mailbox_id = DebugConfig.disableMailboxGroups ? "" : "mailbox_id, ";
String flags;
if (!shared) {
flags = "flags";
} else if (Db.supports(Db.Capability.BITWISE_OPERATIONS)) {
flags = "flags | " + Flag.BITMASK_COPIED;
} else {
flags = "CASE WHEN " + Db.getInstance().bitAND("flags", String.valueOf(Flag.BITMASK_COPIED)) + " <> 0 THEN flags ELSE flags + " + Flag.BITMASK_COPIED + " END";
}
stmt = conn.prepareStatement("INSERT INTO " + table + "(" + mailbox_id + " id, type, parent_id, folder_id, prev_folders, index_id, imap_id, date, size, locator, blob_digest," + " unread, flags, tag_names, sender, subject, name, metadata, mod_metadata, change_date, mod_content) " + "SELECT " + mailbox_id + " ?, type, parent_id, ?, ?, ?, ?, date, size, ?, blob_digest," + " unread, " + flags + ", tag_names, sender, subject, name, metadata, ?, ?, ? FROM " + table + " WHERE " + IN_THIS_MAILBOX_AND + "id = ?");
int pos = 1;
// ID
stmt.setInt(pos++, data.id);
// FOLDER_ID
stmt.setInt(pos++, data.folderId);
stmt.setString(pos++, data.getPrevFolders());
if (data.indexId == MailItem.IndexStatus.NO.id()) {
stmt.setNull(pos++, Types.INTEGER);
} else {
stmt.setInt(pos++, data.indexId);
}
// IMAP_ID
stmt.setInt(pos++, data.imapId);
stmt.setString(pos++, data.locator);
// MOD_METADATA
stmt.setInt(pos++, mbox.getOperationChangeID());
// CHANGE_DATE
stmt.setInt(pos++, mbox.getOperationTimestamp());
// MOD_CONTENT
stmt.setInt(pos++, mbox.getOperationChangeID());
pos = setMailboxId(stmt, mbox, pos);
stmt.setInt(pos++, source.getId());
stmt.executeUpdate();
stmt.close();
boolean needsTag = shared && !source.isTagged(Flag.FlagInfo.COPIED);
if (needsTag || source.getParentId() > 0) {
boolean altersMODSEQ = source.getParentId() > 0;
String updateChangeID = (altersMODSEQ ? ", mod_metadata = ?, change_date = ?" : "");
stmt = conn.prepareStatement("UPDATE " + table + " SET parent_id = NULL, flags = " + flags + updateChangeID + " WHERE " + IN_THIS_MAILBOX_AND + "id = ?");
pos = 1;
if (altersMODSEQ) {
stmt.setInt(pos++, mbox.getOperationChangeID());
stmt.setInt(pos++, mbox.getOperationTimestamp());
}
pos = setMailboxId(stmt, mbox, pos);
stmt.setInt(pos++, source.getId());
stmt.executeUpdate();
stmt.close();
}
if (source instanceof Message && source.getParentId() <= 0) {
changeOpenTargets(source, data.id);
}
MailItem.Type type = MailItem.Type.of(data.type);
DbTag.storeTagReferences(mbox, data.id, type, data.getFlags() | (shared ? Flag.BITMASK_COPIED : 0), data.unreadCount > 0);
DbTag.storeTagReferences(mbox, data.id, type, data.getTags());
} catch (SQLException e) {
// catch item_id uniqueness constraint violation and return failure
if (Db.errorMatches(e, Db.Error.DUPLICATE_ROW)) {
throw MailServiceException.ALREADY_EXISTS(data.id, e);
} else {
throw ServiceException.FAILURE("i-copying " + source.getType() + ": " + source.getId(), e);
}
} finally {
DbPool.closeStatement(stmt);
}
}
use of com.zimbra.cs.mailbox.MailItem in project zm-mailbox by Zimbra.
the class ExportAndDeleteItems method handle.
@Override
public Element handle(Element requst, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
checkRight(zsc, context, null, AdminRight.PR_SYSTEM_ADMIN_ONLY);
// Parse request.
ExportAndDeleteItemsRequest req = JaxbUtil.elementToJaxb(requst);
ExportAndDeleteMailboxSpec mailbox = req.getMailbox();
if (mailbox == null) {
throw ServiceException.INVALID_REQUEST("empty mbox id", null);
}
Mailbox mbox = MailboxManager.getInstance().getMailboxById(mailbox.getId());
Multimap<Integer, Integer> idRevs = HashMultimap.create();
for (ExportAndDeleteItemSpec item : mailbox.getItems()) {
idRevs.put(item.getId(), item.getVersion());
}
String dirPath = req.getExportDir();
String prefix = req.getExportFilenamePrefix();
// Lock the mailbox, to make sure that another thread doesn't modify the items we're exporting/deleting.
mbox.lock.lock();
try {
DbConnection conn = null;
try {
conn = DbPool.getConnection();
if (dirPath != null) {
File exportDir = new File(dirPath);
if (!exportDir.isDirectory()) {
DbPool.quietClose(conn);
throw ServiceException.INVALID_REQUEST(dirPath + " is not a directory", null);
}
String filePath = makePath(dirPath, DbMailItem.TABLE_MAIL_ITEM, prefix);
export(conn, mbox, DbMailItem.TABLE_MAIL_ITEM, "id", idRevs, filePath);
filePath = makePath(dirPath, DbMailItem.TABLE_MAIL_ITEM_DUMPSTER, prefix);
export(conn, mbox, DbMailItem.TABLE_MAIL_ITEM_DUMPSTER, "id", idRevs, filePath);
filePath = makePath(dirPath, DbMailItem.TABLE_REVISION, prefix);
export(conn, mbox, DbMailItem.TABLE_REVISION, "item_id", idRevs, filePath);
filePath = makePath(dirPath, DbMailItem.TABLE_REVISION_DUMPSTER, prefix);
export(conn, mbox, DbMailItem.TABLE_REVISION_DUMPSTER, "item_id", idRevs, filePath);
filePath = makePath(dirPath, DbMailItem.TABLE_APPOINTMENT, prefix);
export(conn, mbox, DbMailItem.TABLE_APPOINTMENT, "item_id", idRevs, filePath);
filePath = makePath(dirPath, DbMailItem.TABLE_APPOINTMENT_DUMPSTER, prefix);
export(conn, mbox, DbMailItem.TABLE_APPOINTMENT_DUMPSTER, "item_id", idRevs, filePath);
}
// delete item from mail_item and revision table
for (Integer itemId : idRevs.keySet()) {
Collection<Integer> revs = idRevs.get(itemId);
for (int rev : revs) {
if (rev == 0) {
// delete all revisions to make sure we delete all blobs
List<MailItem> list = null;
try {
list = mbox.getAllRevisions(null, itemId, MailItem.Type.UNKNOWN);
} catch (NoSuchItemException ex) {
// exception happens when we try to delete a mail_item which is already in mail_item_dumpster
continue;
}
for (MailItem item : list) {
if (item.getType() == MailItem.Type.DOCUMENT) {
mbox.purgeRevision(null, itemId, item.getVersion(), false);
}
}
mbox.delete(null, itemId, MailItem.Type.UNKNOWN, null);
break;
} else if (!revs.contains(0)) {
try {
mbox.purgeRevision(null, itemId, rev, false);
} catch (NoSuchItemException ex) {
// exception happens when we try to delete a revision which is already in revision_dumpster
continue;
}
}
}
}
// Delete items from mail_item_dumpster & revision_dumpster tables just
// incase moved to dumpster tables
DbBlobConsistency.delete(conn, mbox, idRevs);
} finally {
conn.commit();
DbPool.quietClose(conn);
}
} finally {
mbox.lock.release();
}
return zsc.createElement(AdminConstants.EXPORT_AND_DELETE_ITEMS_RESPONSE);
}
use of com.zimbra.cs.mailbox.MailItem in project zm-mailbox by Zimbra.
the class GetMsg method getMsgs.
public static List<Message> getMsgs(OperationContext octxt, Mailbox mbox, List<Integer> iids, boolean read) throws ServiceException {
int i = 0;
int[] msgIdArray = new int[iids.size()];
for (int id : iids) {
msgIdArray[i++] = id;
}
List<Message> toRet = new ArrayList<Message>(msgIdArray.length);
for (MailItem item : mbox.getItemById(octxt, msgIdArray, MailItem.Type.MESSAGE)) {
toRet.add((Message) item);
if (read && item.isUnread() && !RedoLogProvider.getInstance().isSlave()) {
mbox.alterTag(octxt, item.getId(), MailItem.Type.MESSAGE, Flag.FlagInfo.UNREAD, false, null);
}
}
return toRet;
}
Aggregations