use of com.zimbra.cs.mailbox.Mailbox.FolderNode in project zm-mailbox by Zimbra.
the class ShareInfo method getVisibleFolders.
private static Set<Folder> getVisibleFolders(OperationContext octxt, Mailbox mbox) throws ServiceException {
// use the easy one first
Set<Folder> folders = mbox.getVisibleFolders(octxt);
if (folders == null) {
FolderNode root = mbox.getFolderTree(octxt, null, false);
// flatten it
folders = flattenAndSortFolderTree(root);
}
return folders;
}
use of com.zimbra.cs.mailbox.Mailbox.FolderNode in project zm-mailbox by Zimbra.
the class GetFolder method encodeFolderNode.
private static Element encodeFolderNode(FolderNode node, Element parent, ItemIdFormatter ifmt, OperationContext octxt, boolean exposeAclAccessKey, int depth, MailItem.Type view, boolean traverse, List<ExpandableMountpoint> mounts) throws ServiceException {
Element eFolder;
Folder folder = node.mFolder;
if (folder != null) {
eFolder = ToXML.encodeFolder(parent, ifmt, octxt, folder, ToXML.NOTIFY_FIELDS, exposeAclAccessKey);
// if requested, fetch contents of mountpoints
if (traverse && mounts != null && folder instanceof Mountpoint && folder.getMailbox().hasFullAccess(octxt)) {
mounts.add(new ExpandableMountpoint(eFolder, (Mountpoint) folder, depth));
}
} else {
eFolder = parent.addNonUniqueElement(MailConstants.E_FOLDER).addAttribute(MailConstants.A_ID, ifmt.formatItemId(node.mId)).addAttribute(MailConstants.A_NAME, node.mName);
}
if (depth == 0) {
return eFolder;
}
int remainingDepth = depth > 0 ? depth - 1 : depth;
for (FolderNode subNode : node.mSubfolders) {
encodeFolderNode(subNode, eFolder, ifmt, octxt, exposeAclAccessKey, remainingDepth, view, traverse, mounts);
}
return eFolder;
}
use of com.zimbra.cs.mailbox.Mailbox.FolderNode in project zm-mailbox by Zimbra.
the class SoapSession method expandLocalMountpoint.
private void expandLocalMountpoint(OperationContext octxt, Mountpoint mpt, Element.ElementFactory factory, Map<ItemId, Pair<Boolean, Element>> mountpoints) {
// don't bother generating the subhierarchy more than once
ItemId iidTarget = mpt.getTarget();
if (mountpoints.containsKey(iidTarget)) {
return;
}
try {
Provisioning prov = Provisioning.getInstance();
Account owner = prov.get(Key.AccountBy.id, mpt.getOwnerId(), octxt.getAuthToken());
if (owner == null || owner.getId().equals(mAuthenticatedAccountId)) {
mountpoints.put(iidTarget, new Pair<Boolean, Element>(true, null));
return;
}
// if we're non-admin and it's not active
if (Provisioning.ACCOUNT_STATUS_MAINTENANCE.equals(owner.getAccountStatus(prov)) || (!Provisioning.ACCOUNT_STATUS_ACTIVE.equals(owner.getAccountStatus(prov)) && (!octxt.isUsingAdminPrivileges() || !AccessManager.getInstance().canAccessAccount(octxt.getAuthenticatedUser(), owner)))) {
mountpoints.put(iidTarget, new Pair<Boolean, Element>(true, null));
return;
}
// handle mountpoints pointing to a different server later
if (!Provisioning.onLocalServer(owner)) {
mountpoints.put(iidTarget, null);
return;
}
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(owner);
FolderNode remote = mbox.getFolderTree(octxt, new ItemId(mbox, mpt.getRemoteId()), false);
if (remote != null && remote.mFolder != null && !remote.mFolder.isHidden()) {
ItemIdFormatter ifmt = new ItemIdFormatter(octxt.getAuthenticatedUser(), mbox, false);
if (OperationContextData.getNeedGranteeName(octxt)) {
OperationContextData.addGranteeNames(octxt, remote);
}
Element subhierarchy = GetFolder.encodeFolderNode(remote, factory.createElement("ignored"), ifmt, octxt).detach();
mountpoints.put(iidTarget, new Pair<Boolean, Element>(false, subhierarchy));
// fault in a delegate session because there's actually something to listen on...
getDelegateSession(mpt.getOwnerId());
}
} catch (ServiceException e) {
mountpoints.put(iidTarget, new Pair<Boolean, Element>(true, null));
}
}
use of com.zimbra.cs.mailbox.Mailbox.FolderNode in project zm-mailbox by Zimbra.
the class Sync 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);
SyncRequest syncRequest = zsc.elementToJaxb(request);
String token = syncRequest.getToken();
Element response = zsc.createElement(MailConstants.SYNC_RESPONSE);
response.addAttribute(MailConstants.A_CHANGE_DATE, System.currentTimeMillis() / 1000);
// the sync token is of the form "last fully synced change id" (e.g. "32425") or
// last fully synced change id-last item synced in next change id" (e.g. "32425-99213") or
// last fully synced change id-last item synced in next change id and last fully synced delete change id" (e.g. "32425-99213:d1231232") or
// last fully synced change id-last item synced in next change id and
// last fully synced delete id-last item synced in next delete id (e.g. "32425-99213:d12312-82134")
SyncToken syncToken = null;
int tokenInt = 0;
if (!StringUtil.isNullOrEmpty(token)) {
syncToken = new SyncToken(token);
tokenInt = syncToken.getChangeId();
}
if (syncToken == null) {
syncToken = new SyncToken(0);
}
int deleleLimit = syncRequest.getDeleteLimit();
int changeLimit = syncRequest.getChangeLimit();
// server can apply delete pagination through debugconfig/localconfig.
if (deleleLimit <= 0) {
deleleLimit = DebugConfig.syncMaximumDeleteCount;
}
// client specify more than DebugConfig.syncMaximumChangeCount It will use DebugConfig.syncMaximumChangeCount
if (changeLimit <= 0 || changeLimit > DebugConfig.syncMaximumChangeCount) {
changeLimit = DebugConfig.syncMaximumChangeCount;
}
boolean initialSync = tokenInt <= 0;
// permit the caller to restrict initial sync only to calendar items with a recurrence after a given date
long calendarStart = (syncRequest.getCalendarCutoff() != null) ? syncRequest.getCalendarCutoff() : -1;
int messageSyncStart = (syncRequest.getMsgCutoff() != null) ? syncRequest.getMsgCutoff() : -1;
// if the sync is constrained to a folder subset, we need to first figure out what can be seen
Folder root = null;
ItemId iidFolder = null;
try {
iidFolder = new ItemId(request.getAttribute(MailConstants.A_FOLDER, DEFAULT_FOLDER_ID + ""), zsc);
OperationContext octxtOwner = new OperationContext(mbox);
root = mbox.getFolderById(octxtOwner, iidFolder.getId());
} catch (MailServiceException.NoSuchItemException nsie) {
}
Set<Folder> visible = octxt.isDelegatedRequest(mbox) ? mbox.getVisibleFolders(octxt) : null;
FolderNode rootNode = null;
if (root == null || iidFolder == null) {
// resolve grantee names of all ACLs on the mailbox
rootNode = mbox.getFolderTree(octxt, null, true);
} else {
// resolve grantee names of all ACLs on all sub-folders of the requested folder
rootNode = mbox.getFolderTree(octxt, iidFolder, true);
}
OperationContextData.addGranteeNames(octxt, rootNode);
// actually perform the sync
mbox.lock.lock();
try {
mbox.beginTrackingSync();
if (initialSync) {
response.addAttribute(MailConstants.A_TOKEN, mbox.getLastChangeID());
response.addAttribute(MailConstants.A_SIZE, mbox.getSize());
boolean anyFolders = folderSync(response, octxt, ifmt, mbox, root, visible, calendarStart, messageSyncStart, SyncPhase.INITIAL);
// if no folders are visible, add an empty "<folder/>" as a hint
if (!anyFolders) {
response.addElement(MailConstants.E_FOLDER);
}
} else {
boolean typedDeletes = request.getAttributeBool(MailConstants.A_TYPED_DELETES, false);
String newToken = deltaSync(response, octxt, ifmt, mbox, syncToken, deleleLimit, changeLimit, typedDeletes, root, visible, messageSyncStart);
response.addAttribute(MailConstants.A_TOKEN, newToken);
}
} finally {
mbox.lock.release();
}
return response;
}
use of com.zimbra.cs.mailbox.Mailbox.FolderNode in project zm-mailbox by Zimbra.
the class MailboxLockTest method multiAccess.
@Test
public void multiAccess() throws ServiceException {
final Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(MockProvisioning.DEFAULT_ACCOUNT_ID);
// just do some read/write in different threads to see if we trigger any deadlocks or other badness
int numThreads = 5;
final int loopCount = 10;
final long sleepTime = 10;
int joinTimeout = 10000;
List<Thread> threads = new ArrayList<Thread>(numThreads * 2);
for (int i = 0; i < numThreads; i++) {
String threadName = "MailboxLockTest-MultiReader-" + i;
Thread reader = new Thread(threadName) {
@Override
public void run() {
for (int i = 0; i < loopCount; i++) {
mbox.lock.lock(false);
try {
ItemId iid = new ItemId(mbox, Mailbox.ID_FOLDER_USER_ROOT);
FolderNode node = mbox.getFolderTree(null, iid, true);
} catch (ServiceException e) {
e.printStackTrace();
Assert.fail("ServiceException");
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
}
mbox.lock.release();
}
}
};
threads.add(reader);
threadName = "MailboxLockTest-MultiWriter-" + i;
Thread writer = new Thread(threadName) {
@Override
public void run() {
for (int i = 0; i < loopCount; i++) {
mbox.lock.lock(true);
try {
mbox.createFolder(null, "foo-" + Thread.currentThread().getName() + "-" + i, new Folder.FolderOptions().setDefaultView(MailItem.Type.MESSAGE));
} catch (ServiceException e) {
e.printStackTrace();
Assert.fail("ServiceException");
}
mbox.lock.release();
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
}
}
}
};
threads.add(writer);
// writer.start();
// reader.start();
}
for (Thread t : threads) {
t.start();
}
for (Thread t : threads) {
try {
t.join(joinTimeout);
Assert.assertFalse(t.isAlive());
} catch (InterruptedException e) {
}
}
}
Aggregations