use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class ModifyContact 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);
boolean replace = request.getAttributeBool(MailConstants.A_REPLACE, false);
boolean verbose = request.getAttributeBool(MailConstants.A_VERBOSE, true);
Element cn = request.getElement(MailConstants.E_CONTACT);
ItemId iid = new ItemId(cn.getAttribute(MailConstants.A_ID), zsc);
String tagsAttr = cn.getAttribute(MailConstants.A_TAG_NAMES, null);
String[] tags = (tagsAttr == null) ? null : TagUtil.decodeTags(tagsAttr);
Contact contact = mbox.getContactById(octxt, iid.getId());
ParsedContact pc;
if (replace) {
Pair<Map<String, Object>, List<Attachment>> cdata = CreateContact.parseContact(cn, zsc, octxt, contact);
pc = new ParsedContact(cdata.getFirst(), cdata.getSecond());
} else {
pc = CreateContact.parseContactMergeMode(cn, zsc, octxt, contact);
}
if (CreateContact.needToMigrateDlist(zsc)) {
CreateContact.migrateFromDlist(pc);
}
mbox.modifyContact(octxt, iid.getId(), pc);
if (tags != null) {
mbox.setTags(octxt, iid.getId(), MailItem.Type.CONTACT, MailItem.FLAG_UNCHANGED, tags);
}
Contact con = mbox.getContactById(octxt, iid.getId());
Element response = zsc.createElement(MailConstants.MODIFY_CONTACT_RESPONSE);
if (con != null) {
if (verbose)
ToXML.encodeContact(response, ifmt, octxt, con, true, null);
else
response.addElement(MailConstants.E_CONTACT).addAttribute(MailConstants.A_ID, con.getId());
}
return response;
}
use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class NoteAction method handleNote.
private String handleNote(Map<String, Object> context, Element request, String operation) throws ServiceException {
Element action = request.getElement(MailConstants.E_ACTION);
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemId iid = new ItemId(action.getAttribute(MailConstants.A_ID), zsc);
if (operation.equals(OP_EDIT)) {
String content = action.getAttribute(MailConstants.E_CONTENT);
mbox.editNote(octxt, iid.getId(), content);
} else if (operation.equals(OP_REPOSITION)) {
String strBounds = action.getAttribute(MailConstants.A_BOUNDS, null);
mbox.repositionNote(octxt, iid.getId(), new Rectangle(strBounds));
} else
throw ServiceException.INVALID_REQUEST("unknown operation: " + operation, null);
return new ItemIdFormatter(zsc).formatItemId(iid);
}
use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class GetMiniCal method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
Account authAcct = getAuthenticatedAccount(zsc);
OperationContext octxt = getOperationContext(zsc, context);
Element response = getResponseElement(zsc);
long rangeStart = request.getAttributeLong(MailConstants.A_CAL_START_TIME);
long rangeEnd = request.getAttributeLong(MailConstants.A_CAL_END_TIME);
List<ItemId> folderIids = new ArrayList<ItemId>();
for (Iterator<Element> foldersIter = request.elementIterator(MailConstants.E_FOLDER); foldersIter.hasNext(); ) {
Element fElem = foldersIter.next();
ItemId iidFolder = new ItemId(fElem.getAttribute(MailConstants.A_ID), zsc);
folderIids.add(iidFolder);
}
ICalTimeZone tz = parseTimeZone(request);
if (tz == null)
// requestor's time zone, not mailbox owner's
tz = Util.getAccountTimeZone(authAcct);
TreeSet<String> busyDates = new TreeSet<String>();
Provisioning prov = Provisioning.getInstance();
MailboxManager mboxMgr = MailboxManager.getInstance();
Server localServer = prov.getLocalServer();
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
Map<ItemId, Resolved> resolved = resolveMountpoints(octxt, mbox, folderIids);
Map<ItemId, ItemId> /* requested iid */
reverseMap = new HashMap<ItemId, ItemId>();
for (Map.Entry<ItemId, Resolved> entry : resolved.entrySet()) {
ItemId requestedIid = entry.getKey();
Resolved res = entry.getValue();
if (res.error == null) {
reverseMap.put(res.iid, requestedIid);
} else {
addError(response, ifmt.formatItemId(requestedIid), res.error.getCode(), res.error.getMessage());
}
}
Map<Server, Map<String, List<Integer>>> /* folder ids */
groupedByServer = Search.groupByServer(groupFoldersByAccount(resolved));
// Look up in calendar cache first.
if (LC.calendar_cache_enabled.booleanValue()) {
CalSummaryCache calCache = CalendarCacheManager.getInstance().getSummaryCache();
Calendar cal = new GregorianCalendar(tz);
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();
// for each folder
for (Iterator<Integer> iterFolderId = folderIds.iterator(); iterFolderId.hasNext(); ) {
int folderId = iterFolderId.next();
try {
CalendarDataResult result = calCache.getCalendarSummary(octxt, acctId, folderId, MailItem.Type.APPOINTMENT, rangeStart, rangeEnd, true);
if (result != null) {
// Found data in cache.
iterFolderId.remove();
addBusyDates(cal, result.data, rangeStart, rangeEnd, busyDates);
}
} catch (ServiceException e) {
iterFolderId.remove();
ItemId iid = new ItemId(acctId, folderId);
// Error must mention folder id requested by client.
ItemId reqIid = reverseMap.get(iid);
if (reqIid != null) {
ZimbraLog.calendar.warn("Error accessing calendar folder " + ifmt.formatItemId(reqIid), e);
addError(response, ifmt.formatItemId(reqIid), e.getCode(), e.getMessage());
} else {
ZimbraLog.calendar.warn("Error accessing calendar folder; resolved id=" + ifmt.formatItemId(iid) + " (missing reverse mapping)", e);
addError(response, ifmt.formatItemId(iid), e.getCode(), e.getMessage());
}
}
}
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();
Account targetAcct = prov.get(AccountBy.id, acctId);
if (targetAcct == null) {
ZimbraLog.calendar.warn("Skipping unknown account " + acctId + " during minical search");
continue;
}
Mailbox targetMbox = mboxMgr.getMailboxByAccount(targetAcct);
for (int folderId : folderIds) {
try {
doLocalFolder(octxt, tz, targetMbox, folderId, rangeStart, rangeEnd, busyDates);
} catch (ServiceException e) {
ItemId iid = new ItemId(acctId, folderId);
// Error must mention folder id requested by client.
ItemId reqIid = reverseMap.get(iid);
if (reqIid != null) {
ZimbraLog.calendar.warn("Error accessing calendar folder " + ifmt.formatItemId(reqIid), e);
addError(response, ifmt.formatItemId(reqIid), e.getCode(), e.getMessage());
} else {
ZimbraLog.calendar.warn("Error accessing calendar folder; resolved id=" + ifmt.formatItemId(iid) + " (missing reverse mapping)", e);
addError(response, ifmt.formatItemId(iid), e.getCode(), e.getMessage());
}
}
}
}
} else {
// remote server
// mail service soap requests want to see a target account
String nominalTargetAcctId = null;
List<String> folderList = new ArrayList<String>();
for (Map.Entry<String, List<Integer>> entry : accountFolders.entrySet()) {
String acctId = entry.getKey();
if (nominalTargetAcctId == null)
nominalTargetAcctId = acctId;
ItemIdFormatter ifmtRemote = new ItemIdFormatter(authAcct.getId(), acctId, false);
List<Integer> folderIds = entry.getValue();
for (int folderId : folderIds) {
folderList.add(ifmtRemote.formatItemId(folderId));
}
}
doRemoteFolders(zsc, nominalTargetAcctId, folderList, rangeStart, rangeEnd, busyDates, response, reverseMap, ifmt);
}
}
for (String datestamp : busyDates) {
Element dateElem = response.addElement(MailConstants.E_CAL_MINICAL_DATE);
dateElem.setText(datestamp);
}
return response;
}
use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class GetMiniCal method resolveMountpoints.
// Resolve mountpoints for each requested folder. Resolution can result in error per folder. Typical errors
// include PERM_DENIED (if sharer revoked permission), NO_SUCH_FOLDER (if sharer deleted shared folder), and
// NO_SUCH_ACCOUNT (if sharer account has been deleted).
private static Map<ItemId, Resolved> resolveMountpoints(OperationContext octxt, Mailbox mbox, List<ItemId> folderIids) {
Map<ItemId, Resolved> result = new HashMap<ItemId, Resolved>();
for (ItemId iidFolder : folderIids) {
String targetAccountId = iidFolder.getAccountId();
int folderId = iidFolder.getId();
try {
ServiceException error = null;
if (mbox.getAccountId().equals(targetAccountId)) {
boolean isMountpoint = true;
int hopCount = 0;
// resolve local mountpoint to a real folder; deal with possible mountpoint chain
while (isMountpoint && hopCount < ZimbraSoapContext.MAX_HOP_COUNT) {
Folder folder = mbox.getFolderById(octxt, folderId);
isMountpoint = folder instanceof Mountpoint;
if (isMountpoint) {
Mountpoint mp = (Mountpoint) folder;
folderId = mp.getRemoteId();
if (!mp.isLocal()) {
// done resolving if pointing to a different account
targetAccountId = mp.getOwnerId();
Account targetAcct = Provisioning.getInstance().get(Key.AccountBy.id, targetAccountId);
if (targetAcct == null)
error = AccountServiceException.NO_SUCH_ACCOUNT(targetAccountId);
break;
}
hopCount++;
}
}
if (hopCount >= ZimbraSoapContext.MAX_HOP_COUNT)
error = MailServiceException.TOO_MANY_HOPS(iidFolder);
}
result.put(iidFolder, new Resolved(new ItemId(targetAccountId, folderId), error));
} catch (ServiceException e) {
ItemIdFormatter ifmt = new ItemIdFormatter();
ZimbraLog.calendar.warn("Error resolving calendar folder " + ifmt.formatItemId(iidFolder), e);
result.put(iidFolder, new Resolved(new ItemId(targetAccountId, folderId), e));
}
}
return result;
}
use of com.zimbra.cs.service.util.ItemIdFormatter in project zm-mailbox by Zimbra.
the class GetMsg 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 eMsg = request.getElement(MailConstants.E_MSG);
ItemId iid = new ItemId(eMsg.getAttribute(MailConstants.A_ID), zsc);
String part = eMsg.getAttribute(MailConstants.A_PART, null);
MsgContent wantContent = MsgContent.fromString(eMsg.getAttribute(MailConstants.A_WANT_CONTENT, null));
wantContent = wantContent == null ? MsgContent.full : wantContent;
boolean raw = eMsg.getAttributeBool(MailConstants.A_RAW, false);
boolean read = eMsg.getAttributeBool(MailConstants.A_MARK_READ, false);
int maxSize = (int) eMsg.getAttributeLong(MailConstants.A_MAX_INLINED_LENGTH, 0);
boolean wantHTML = eMsg.getAttributeBool(MailConstants.A_WANT_HTML, false);
boolean neuter = eMsg.getAttributeBool(MailConstants.A_NEUTER, true);
Set<String> headers = null;
for (Element eHdr : eMsg.listElements(MailConstants.A_HEADER)) {
if (headers == null)
headers = new HashSet<String>();
headers.add(eHdr.getAttribute(MailConstants.A_ATTRIBUTE_NAME));
}
boolean needGroupInfo = eMsg.getAttributeBool(MailConstants.A_NEED_EXP, false);
Element response = zsc.createElement(MailConstants.GET_MSG_RESPONSE);
if (iid.hasSubpart()) {
// calendar item
CalendarItem calItem = getCalendarItem(octxt, mbox, iid);
if (raw) {
throw ServiceException.INVALID_REQUEST("Cannot request RAW formatted subpart message", null);
} else {
String recurIdZ = eMsg.getAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, null);
if (recurIdZ == null) {
// If not specified, try to get it from the Invite.
int invId = iid.getSubpartId();
Invite[] invs = calItem.getInvites(invId);
if (invs.length > 0) {
RecurId rid = invs[0].getRecurId();
if (rid != null)
recurIdZ = rid.getDtZ();
}
}
ToXML.encodeInviteAsMP(response, ifmt, octxt, calItem, recurIdZ, iid, part, maxSize, wantHTML, neuter, headers, false, needGroupInfo);
}
} else {
Message msg = getMsg(octxt, mbox, iid, read);
if (raw) {
ToXML.encodeMessageAsMIME(response, ifmt, octxt, msg, part, false);
} else {
ToXML.encodeMessageAsMP(response, ifmt, octxt, msg, part, maxSize, wantHTML, neuter, headers, false, needGroupInfo, LC.mime_encode_missing_blob.booleanValue(), wantContent);
}
}
return response;
}
Aggregations